diff --git a/bts_podcast/bts_podcast.php b/bts_podcast/bts_podcast.php
index 36595b5..759acd8 100644
--- a/bts_podcast/bts_podcast.php
+++ b/bts_podcast/bts_podcast.php
@@ -19,7 +19,7 @@ $plugin['flags'] = PLUGIN_LIFECYCLE_NOTIFY;
// @include_once('zem_tpl.php');
register_callback('bts_podcast_initdb','plugin_lifecycle.bts_podcast', 'enabled');
-register_callback('bts_podcast_genguid','article_saved');
+register_callback('bts_podcast_gen_metainfo','article_saved');
if (0) {
?>
@@ -88,15 +88,21 @@ This plugin creates a *sha256* table in your Textpattern DB. There, it stores th
# --- BEGIN PLUGIN CODE ---
-// Hooks
+// Hooks/callbacks
function bts_podcast_initdb () {
- safe_query("CREATE TABLE IF NOT EXISTS sha256 (id int(11) NOT NULL AUTO_INCREMENT,url_title varchar(64) NOT NULL,filename varchar(64) NOT NULL,type char(3) NOT NULL,checksum char(64) NOT NULL,created datetime NOT NULL DEFAULT CURRENT_TIMESTAMP,changed timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,PRIMARY KEY (id),UNIQUE KEY `unique_index` (url_title,type)");
+ safe_query("CREATE TABLE IF NOT EXISTS bts_podcast (id int(11) NOT NULL AUTO_INCREMENT,url_title varchar(64) NOT NULL,filename varchar(64) NOT NULL,type char(3) NOT NULL,checksum char(64) NOT NULL,bytesize varchar(16) NOT NULL,created datetime NOT NULL DEFAULT CURRENT_TIMESTAMP,changed timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,PRIMARY KEY (id),UNIQUE KEY unique_index (url_title,type)) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=utf8");
}
-function bts_podcast_gen_guid () {
- hash_file('sha256',file_article_upload());
+function bts_podcast_gen_metainfo ($input) {
+ $hash = hash_file('sha256',file_article_upload());
+// safe_query("INSERT INTO bts_podcast (url_title,filename,type,checksum,bytesize) VALUES ('" . $input['urltitle'] . "','" . $input['mediafile'] . "','" . $input['mediatype'] . "','" . $input['mediachksum'] . "','" . $input['mediabytes'] . "') ON DUPLICATE KEY UPDATE url_title = '" . $input['urltitle'] . "', filename = '" . $input['mediafile'] . "', type = '" . $input['mediatype'] . "', checksum = '" . $input['mediachksum'] . "', bytesize = '" . $input['mediabytes'] . "'");
}
+//use pluggable_ui(event,step,default content, record set)
+//event, i believe, is article_ui
+//maybe use step "custom_fields" and totally replace custom fields with the file uploader?
+//i should also find a way to get the "S0E0" format automatically used for the url title/permlink.
+
// Register the plugin...
if(class_exists('\Textpattern\Tag\Registry')) {
Txp::get('\Textpattern\Tag\Registry')
@@ -142,7 +148,7 @@ function bts_podcast_guid ($atts) {
), $atts));
if (($byte == '1' && $db == '1') || ($string == '')) {
- $checksum = fetch('checksum','sha256','filename',bts_podcast_filename($atts));
+ $checksum = fetch('checksum','bts_podcast','filename',bts_podcast_filename($atts));
} elseif ($byte == '1') {
$checksum = hash_file('sha256',$string);
} else {
@@ -156,13 +162,49 @@ function bts_podcast_media_uri ($atts) {
$default_vals = array('media' => 'mp3');
$default_vals['uri'] = site_url($atts) . bts_podcast_path($atts) . bts_podcast_filename($atts);
extract(lAtts(array($default_vals), $atts));
- if ( $uri == '') {
+ if (! isset($uri)) {
$uri = site_url($atts) . bts_podcast_path($atts) . bts_podcast_filename($atts);
}
return $uri;
}
+/*
+function bts_podccast_filesize($atts) {
+}
+function bts_podcast_medialength($atts) {
+}
+function bts_podcast_get_guid($atts) {
+}
+*/
+// UNDER DEVELOPMENT: needs bts_podcast_filesize (which i need to rename to actually be bytesize)
+// i also need to get media length so that can be returned in the actual feed.
+/*
+$metainfo_mp3 = array(
+ //$input['urltitle']
+ //$input['mediafile']
+ //$input['mediatype']
+ //$input['mediachksum']
+ //$input['mediabytes']
+ urltitle => title($atts),
+ mediafile => bts_podcast_filename($atts),
+ mediatype => 'mp3',
+ mediachksum => bts_podcast_guid($atts),
+ mediabytes => bts_podcast_filesize($atts));
+$metainfo_ogg = array(
+ //$input['urltitle']
+ //$input['mediafile']
+ //$input['mediatype']
+ //$input['mediachksum']
+ //$input['mediabytes']
+ urltitle => title($atts),
+ mediafile => bts_podcast_filename($atts),
+ mediatype => 'mp3',
+ mediachksum => bts_podcast_guid($atts),
+ mediabytes => bts_podcast_filesize($atts));
+bts_podcast_gen_metainfo ($metainfo_mp3);
+bts_podcast_gen_metainfo ($metainfo_ogg);
+*/
# --- END PLUGIN CODE ---
?>
diff --git a/upm_file_popper-0.2.2.diff b/upm_file_popper-0.2.2.diff
new file mode 100644
index 0000000..bf168e6
--- /dev/null
+++ b/upm_file_popper-0.2.2.diff
@@ -0,0 +1,91 @@
+--- upm_file_popper-0.2.2.orig 2016-01-01 17:13:48.000000000 +0100
++++ upm_file_popper-0.2.2.new 2016-01-01 17:13:48.000000000 +0100
+@@ -1,6 +1,6 @@
+-if (txpinterface == 'admin')
++if (@txpinterface == 'admin')
+ {
+ add_privs('upm_file_popper', '1,2,3,4,5');
+ register_callback('upm_file_popper', 'upm_file_popper');
+
+ add_privs('upm_file_popper_link', '1,2,3,4,5');
+@@ -9,12 +9,25 @@
+ add_privs('upm_file_popper_js', '1,2,3,4,5');
+ register_callback('upm_file_popper_js', 'upm_file_popper_js', '', 1);
+
+ add_privs('upm_file_popper_img', '1,2,3,4,5');
+ register_callback('upm_file_popper_img', 'upm_file_popper_img', '', 1);
++
++ register_callback('upm_file_popper_menu', 'article_ui', 'extend_col_1');
++
+ }
+
++ /**
++ * Insert upm_file_popper link in column 1 on the write-tab
++ *
++ * @param string $event (article_ui)
++ * @param string $step (extend_col_1)
++ */
++ function upm_file_popper_menu($event, $step) {
++ return '
';
++ }
++
+ // -------------------------------------------------------------
+
+ function upm_file_popper()
+ {
+ global $step, $prefs;
+@@ -88,13 +101,14 @@
+
+
+ css;
+
+ extract(gpsa(array('page', 'sort', 'dir', 'crit', 'search_method')));
++ if ($sort === '') $sort = get_pref('file_sort_column', 'filename');
++ if ($dir === '') $dir = get_pref('file_sort_dir', 'asc');
++ $dir = ($dir == 'desc') ? 'desc' : 'asc';
+
+- $dir = ($dir == 'desc') ? 'desc' : 'asc';
+-
+ switch ($sort)
+ {
+ case 'id':
+ $sort_sql = "id $dir, filename asc";
+ break;
+@@ -183,11 +197,11 @@
+
+ if ($rs)
+ {
+ $sort_link = 'upm_file_popper'.a.'bm=true';
+
+- echo startTable('list'),
++ echo startTable('','','txp-list'),
+ tr(
+ column_head('ID', 'id', $sort_link, true, $switch_dir, $crit, $search_method).
+ column_head('file_name', 'filename', $sort_link, true, $switch_dir, $crit, $search_method).
+ column_head('description', 'description', $sort_link, true, $switch_dir, $crit, $search_method).
+ column_head('file_category', 'category', $sort_link, true, $switch_dir, $crit, $search_method).
+@@ -397,21 +411,21 @@
+ $('#upm_file_popper_start').val( $('body').val() );
+
+ // ------------------------------
+ // create and insert popup link
+
+- var w = 575;
+- var h = 375;
++ var w = 800;
++ var h = 500;
+
+ var t = (screen.height) ? (screen.height - h) / 2 : 0;
+ var l = (screen.width) ? (screen.width - w) / 2 : 0;
+
+ var a = $(document.createElement('a')).
+ text('$lang_attach_file').
+ attr({
+ target: '_blank',
+- href: '?event=upm_file_popper\u0026bm=1'
++ href: '?event=upm_file_popper\u0026bm=1\u0026sort=id\u0026dir=desc'
+ }).
+ click(function () {
+ var upm_file_popper = window.open(this.href, 'upm_file_popper', 'top = '+t+', left = '+l+', width = '+w+', height = '+h+', toolbar = no, location = no, directories = no, status = yes, menubar = no, scrollbars = yes, copyhistory = no, resizable = yes');
+ upm_file_popper.focus();
+ return false;
diff --git a/upm_file_popper-0.2.2.old b/upm_file_popper-0.2.2.old
new file mode 100644
index 0000000..f7c37d3
--- /dev/null
+++ b/upm_file_popper-0.2.2.old
@@ -0,0 +1,636 @@
+if (txpinterface == 'admin')
+ {
+ add_privs('upm_file_popper', '1,2,3,4,5');
+ register_callback('upm_file_popper', 'upm_file_popper');
+
+ add_privs('upm_file_popper_link', '1,2,3,4,5');
+ register_callback('upm_file_popper_link', 'article');
+
+ add_privs('upm_file_popper_js', '1,2,3,4,5');
+ register_callback('upm_file_popper_js', 'upm_file_popper_js', '', 1);
+
+ add_privs('upm_file_popper_img', '1,2,3,4,5');
+ register_callback('upm_file_popper_img', 'upm_file_popper_img', '', 1);
+ }
+
+// -------------------------------------------------------------
+
+ function upm_file_popper()
+ {
+ global $step, $prefs;
+
+ if ($step == 'upm_file_popper_change_pageby')
+ {
+ event_change_pageby('file');
+ $GLOBALS['prefs'] = get_prefs();
+ }
+
+ upm_file_popper_list();
+ }
+
+// -------------------------------------------------------------
+
+ function upm_file_popper_list()
+ {
+ global $file_base_path, $prefs;
+
+ pagetop(upm_file_popper_gTxt('file_selector'));
+
+ echo <<
+
+
+
+
+css;
+
+ extract(gpsa(array('page', 'sort', 'dir', 'crit', 'search_method')));
+
+ $dir = ($dir == 'desc') ? 'desc' : 'asc';
+
+ switch ($sort)
+ {
+ case 'id':
+ $sort_sql = "id $dir, filename asc";
+ break;
+
+ case 'filename':
+ $sort_sql = "filename $dir";
+ break;
+
+ case 'description':
+ $sort_sql = 'description '.$dir.', filename desc';
+ break;
+
+ case 'category':
+ $sort_sql = "category $dir, filename asc";
+ break;
+
+ case 'downloads':
+ $sort_sql = "downloads $dir, filename asc";
+ break;
+
+ default:
+ $dir = 'desc';
+ $sort_sql = "filename $dir";
+ break;
+ }
+
+ $switch_dir = ($dir == 'desc') ? 'asc' : 'desc';
+
+ $criteria = 1;
+
+ if ($search_method and $crit)
+ {
+ $crit_escaped = doSlash($crit);
+
+ $critsql = array(
+ 'id' => "id = '$crit_escaped'",
+ 'filename' => "filename like '%$crit_escaped%'",
+ 'category' => "category like '%$crit_escaped%'",
+ 'description' => "description like '%$crit_escaped%'"
+ );
+
+ if (array_key_exists($search_method, $critsql))
+ {
+ $criteria = $critsql[$search_method];
+ $limit = 500;
+ }
+
+ else
+ {
+ $search_method = '';
+ $crit = '';
+ }
+ }
+
+ else
+ {
+ $search_method = '';
+ $crit = '';
+ }
+
+ $total = safe_count('txp_file', "$criteria");
+
+ if ($total < 1)
+ {
+ if ($criteria != 1)
+ {
+ echo n.upm_file_popper_search_form($crit, $search_method, $sort, $dir).
+ n.graf(gTxt('no_results_found'), ' style="text-align: center;"');
+ }
+
+ else
+ {
+ echo n.graf(gTxt('no_files_recorded'), ' style="text-align: center;"');
+ }
+
+ return;
+ }
+
+ $limit = max($prefs['file_list_pageby'], 15);
+
+ list($page, $offset, $numPages) = pager($total, $limit, $page);
+
+ echo upm_file_popper_search_form($crit, $search_method, $sort, $dir);
+
+ $rs = safe_rows_start('*', 'txp_file', "$criteria order by $sort_sql limit $offset, $limit");
+
+ if ($rs)
+ {
+ $sort_link = 'upm_file_popper'.a.'bm=true';
+
+ echo startTable('list'),
+ tr(
+ column_head('ID', 'id', $sort_link, true, $switch_dir, $crit, $search_method).
+ column_head('file_name', 'filename', $sort_link, true, $switch_dir, $crit, $search_method).
+ column_head('description', 'description', $sort_link, true, $switch_dir, $crit, $search_method).
+ column_head('file_category', 'category', $sort_link, true, $switch_dir, $crit, $search_method).
+ hCell().
+ hCell(gTxt('tags')).
+ hCell(gTxt('status')).
+ column_head('downloads', 'downloads', $sort_link, true, $switch_dir, $crit, $search_method)
+ );
+
+ while ($a = nextRow($rs))
+ {
+ extract($a);
+
+ // god I hate javascript in php
+ $insert = '';
+
+ $tag_url = '?event=tag'.a.'tag_name=file_download_link'.a.'id='.$id.a.'description='.urlencode($description).
+ a.'filename='.urlencode($filename);
+
+ $file_exists = file_exists(build_file_path($file_base_path, $filename));
+
+ $status = ($file_exists) ?
+ ''.gTxt('file_status_ok').'' :
+ ''.gTxt('file_status_missing').'';
+
+ if (!isset($downloads))
+ {
+ safe_alter('txp_file', "ADD downloads INT DEFAULT '0' NOT NULL");
+ $downloads = 0;
+ }
+
+ elseif (empty($downloads))
+ {
+ $downloads = '0';
+ }
+
+
+ echo n.n.tr(
+
+ n.td($id).
+
+ td(''.$filename.'', 125).
+
+ td($description, 150).
+ td($category, 90).
+
+ td($insert).
+
+ td(
+ n.''
+ , 75).
+
+ td($status, 45).
+
+ td(
+ ($downloads == '0' ? gTxt('none') : $downloads)
+ , 25)
+ );
+ }
+
+ echo endTable().
+
+ nav_form('upm_file_popper', $page, $numPages, $sort, $dir, $crit, $search_method).
+
+ upm_file_popper_pageby_form().
+
+ n.tag(
+ n.graf(upm_file_popper_gTxt('return')).
+ n.graf(''.gTxt('yes').'.'.
+ ' '.gTxt('no').'.')
+ , 'div', ' id="return" style="display: none; width: 200px; height: 75px;"').
+
+ n.graf(upm_file_popper_gTxt('success'), ' id="success" style="display: none; width: 150px; height: 35px;"').
+ n.graf(upm_file_popper_gTxt('failed'), ' id="failed" style="display: none; width: 150px; height: 35px;"');
+ }
+ }
+
+// -------------------------------------------------------------
+
+ function upm_file_popper_search_form($crit, $method, $sort, $dir)
+ {
+ $default_method = 'filename';
+
+ $method = ($method) ? $method : $default_method;
+
+ $methods = array(
+ 'id' => gTxt('id'),
+ 'filename' => gTxt('file_name'),
+ 'description' => gTxt('description'),
+ 'category' => gTxt('file_category')
+ );
+
+ return n.n.'';
+ }
+
+// -------------------------------------------------------------
+
+ function upm_file_popper_pageby_form()
+ {
+ global $prefs;
+
+ $vals = array(
+ 15 => 15,
+ 25 => 25,
+ 50 => 50,
+ 100 => 100
+ );
+
+ $select_page = selectInput('qty', $vals, $prefs['file_list_pageby'], '', 1);
+
+ // proper localisation
+ $page = str_replace('{page}', $select_page, gTxt('view_per_page'));
+
+ return form(
+ ''.
+ $page.
+ eInput('upm_file_popper').
+ sInput('upm_file_popper_change_pageby').
+ hInput('bm', '1').
+ ''.
+ '
'
+ );
+ }
+
+// -------------------------------------------------------------
+
+ function upm_file_popper_link()
+ {
+ $view = gps('view');
+
+ if ($view == 'text' or empty($view))
+ {
+ echo <<
+
+
+form;
+ }
+ }
+
+// -------------------------------------------------------------
+
+ function upm_file_popper_js()
+ {
+ global $prefs;
+
+ while (@ob_end_clean());
+
+ header("Content-type: text/javascript");
+
+ if (empty($prefs['upm_file_field']))
+ {
+ $lang_forgot_field = upm_file_popper_gTxt('forgot_field');
+
+ echo << a:contains("$txt")').
+ before(link);
+});
+js;
+
+ exit(0);
+ }
+
+ elseif (gps('name') == 'pop')
+ {
+ $lang_check_leave = upm_file_popper_gTxt('check_leave');
+
+ echo << 'Attach',
+ 'attach_file' => 'Attach File',
+ 'check_leave' => 'You have made changes to the current post which you have not saved. Continue without saving?',
+ 'description_for' => 'Description for',
+ 'failed' => 'Insert failed.',
+ 'file_selector' => 'File Selector',
+ 'forgot_field' => 'You forgot to define the custom field for upm_file/upm_file_popper to use. Ensure that you have a custom field available, and that you have upm_file installed and activated, then visit Extensions > upm_file.',
+ 'no_description' => 'No description has been defined for this file.',
+ 'packet_custom_field' => 'Packet Custom Field',
+ 'return' => 'Return to editing the post?',
+ 'success' => 'Success.',
+ 'view_all' => 'View All'
+ );
+
+ return strtr($lang[$var], $atts);
+ }
diff --git a/upm_file_popper-0.2.2.orig b/upm_file_popper-0.2.2.orig
new file mode 100644
index 0000000..b5a23c0
--- /dev/null
+++ b/upm_file_popper-0.2.2.orig
@@ -0,0 +1,650 @@
+if (@txpinterface == 'admin')
+ {
+ add_privs('upm_file_popper', '1,2,3,4,5');
+ register_callback('upm_file_popper', 'upm_file_popper');
+
+ add_privs('upm_file_popper_link', '1,2,3,4,5');
+ register_callback('upm_file_popper_link', 'article');
+
+ add_privs('upm_file_popper_js', '1,2,3,4,5');
+ register_callback('upm_file_popper_js', 'upm_file_popper_js', '', 1);
+
+ add_privs('upm_file_popper_img', '1,2,3,4,5');
+ register_callback('upm_file_popper_img', 'upm_file_popper_img', '', 1);
+
+ register_callback('upm_file_popper_menu', 'article_ui', 'extend_col_1');
+
+ }
+
+ /**
+ * Insert upm_file_popper link in column 1 on the write-tab
+ *
+ * @param string $event (article_ui)
+ * @param string $step (extend_col_1)
+ */
+ function upm_file_popper_menu($event, $step) {
+ return '';
+ }
+
+// -------------------------------------------------------------
+
+ function upm_file_popper()
+ {
+ global $step, $prefs;
+
+ if ($step == 'upm_file_popper_change_pageby')
+ {
+ event_change_pageby('file');
+ $GLOBALS['prefs'] = get_prefs();
+ }
+
+ upm_file_popper_list();
+ }
+
+// -------------------------------------------------------------
+
+ function upm_file_popper_list()
+ {
+ global $file_base_path, $prefs;
+
+ pagetop(upm_file_popper_gTxt('file_selector'));
+
+ echo <<
+
+
+
+
+css;
+
+ extract(gpsa(array('page', 'sort', 'dir', 'crit', 'search_method')));
+ if ($sort === '') $sort = get_pref('file_sort_column', 'filename');
+ if ($dir === '') $dir = get_pref('file_sort_dir', 'asc');
+ $dir = ($dir == 'desc') ? 'desc' : 'asc';
+
+ switch ($sort)
+ {
+ case 'id':
+ $sort_sql = "id $dir, filename asc";
+ break;
+
+ case 'filename':
+ $sort_sql = "filename $dir";
+ break;
+
+ case 'description':
+ $sort_sql = 'description '.$dir.', filename desc';
+ break;
+
+ case 'category':
+ $sort_sql = "category $dir, filename asc";
+ break;
+
+ case 'downloads':
+ $sort_sql = "downloads $dir, filename asc";
+ break;
+
+ default:
+ $dir = 'desc';
+ $sort_sql = "filename $dir";
+ break;
+ }
+
+ $switch_dir = ($dir == 'desc') ? 'asc' : 'desc';
+
+ $criteria = 1;
+
+ if ($search_method and $crit)
+ {
+ $crit_escaped = doSlash($crit);
+
+ $critsql = array(
+ 'id' => "id = '$crit_escaped'",
+ 'filename' => "filename like '%$crit_escaped%'",
+ 'category' => "category like '%$crit_escaped%'",
+ 'description' => "description like '%$crit_escaped%'"
+ );
+
+ if (array_key_exists($search_method, $critsql))
+ {
+ $criteria = $critsql[$search_method];
+ $limit = 500;
+ }
+
+ else
+ {
+ $search_method = '';
+ $crit = '';
+ }
+ }
+
+ else
+ {
+ $search_method = '';
+ $crit = '';
+ }
+
+ $total = safe_count('txp_file', "$criteria");
+
+ if ($total < 1)
+ {
+ if ($criteria != 1)
+ {
+ echo n.upm_file_popper_search_form($crit, $search_method, $sort, $dir).
+ n.graf(gTxt('no_results_found'), ' style="text-align: center;"');
+ }
+
+ else
+ {
+ echo n.graf(gTxt('no_files_recorded'), ' style="text-align: center;"');
+ }
+
+ return;
+ }
+
+ $limit = max($prefs['file_list_pageby'], 15);
+
+ list($page, $offset, $numPages) = pager($total, $limit, $page);
+
+ echo upm_file_popper_search_form($crit, $search_method, $sort, $dir);
+
+ $rs = safe_rows_start('*', 'txp_file', "$criteria order by $sort_sql limit $offset, $limit");
+
+ if ($rs)
+ {
+ $sort_link = 'upm_file_popper'.a.'bm=true';
+
+ echo startTable('','','txp-list'),
+ tr(
+ column_head('ID', 'id', $sort_link, true, $switch_dir, $crit, $search_method).
+ column_head('file_name', 'filename', $sort_link, true, $switch_dir, $crit, $search_method).
+ column_head('description', 'description', $sort_link, true, $switch_dir, $crit, $search_method).
+ column_head('file_category', 'category', $sort_link, true, $switch_dir, $crit, $search_method).
+ hCell().
+ hCell(gTxt('tags')).
+ hCell(gTxt('status')).
+ column_head('downloads', 'downloads', $sort_link, true, $switch_dir, $crit, $search_method)
+ );
+
+ while ($a = nextRow($rs))
+ {
+ extract($a);
+
+ // god I hate javascript in php
+ $insert = '';
+
+ $tag_url = '?event=tag'.a.'tag_name=file_download_link'.a.'id='.$id.a.'description='.urlencode($description).
+ a.'filename='.urlencode($filename);
+
+ $file_exists = file_exists(build_file_path($file_base_path, $filename));
+
+ $status = ($file_exists) ?
+ ''.gTxt('file_status_ok').'' :
+ ''.gTxt('file_status_missing').'';
+
+ if (!isset($downloads))
+ {
+ safe_alter('txp_file', "ADD downloads INT DEFAULT '0' NOT NULL");
+ $downloads = 0;
+ }
+
+ elseif (empty($downloads))
+ {
+ $downloads = '0';
+ }
+
+
+ echo n.n.tr(
+
+ n.td($id).
+
+ td(''.$filename.'', 125).
+
+ td($description, 150).
+ td($category, 90).
+
+ td($insert).
+
+ td(
+ n.''
+ , 75).
+
+ td($status, 45).
+
+ td(
+ ($downloads == '0' ? gTxt('none') : $downloads)
+ , 25)
+ );
+ }
+
+ echo endTable().
+
+ nav_form('upm_file_popper', $page, $numPages, $sort, $dir, $crit, $search_method).
+
+ upm_file_popper_pageby_form().
+
+ n.tag(
+ n.graf(upm_file_popper_gTxt('return')).
+ n.graf(''.gTxt('yes').'.'.
+ ' '.gTxt('no').'.')
+ , 'div', ' id="return" style="display: none; width: 200px; height: 75px;"').
+
+ n.graf(upm_file_popper_gTxt('success'), ' id="success" style="display: none; width: 150px; height: 35px;"').
+ n.graf(upm_file_popper_gTxt('failed'), ' id="failed" style="display: none; width: 150px; height: 35px;"');
+ }
+ }
+
+// -------------------------------------------------------------
+
+ function upm_file_popper_search_form($crit, $method, $sort, $dir)
+ {
+ $default_method = 'filename';
+
+ $method = ($method) ? $method : $default_method;
+
+ $methods = array(
+ 'id' => gTxt('id'),
+ 'filename' => gTxt('file_name'),
+ 'description' => gTxt('description'),
+ 'category' => gTxt('file_category')
+ );
+
+ return n.n.'';
+ }
+
+// -------------------------------------------------------------
+
+ function upm_file_popper_pageby_form()
+ {
+ global $prefs;
+
+ $vals = array(
+ 15 => 15,
+ 25 => 25,
+ 50 => 50,
+ 100 => 100
+ );
+
+ $select_page = selectInput('qty', $vals, $prefs['file_list_pageby'], '', 1);
+
+ // proper localisation
+ $page = str_replace('{page}', $select_page, gTxt('view_per_page'));
+
+ return form(
+ ''.
+ $page.
+ eInput('upm_file_popper').
+ sInput('upm_file_popper_change_pageby').
+ hInput('bm', '1').
+ ''.
+ '
'
+ );
+ }
+
+// -------------------------------------------------------------
+
+ function upm_file_popper_link()
+ {
+ $view = gps('view');
+
+ if ($view == 'text' or empty($view))
+ {
+ echo <<
+
+
+form;
+ }
+ }
+
+// -------------------------------------------------------------
+
+ function upm_file_popper_js()
+ {
+ global $prefs;
+
+ while (@ob_end_clean());
+
+ header("Content-type: text/javascript");
+
+ if (empty($prefs['upm_file_field']))
+ {
+ $lang_forgot_field = upm_file_popper_gTxt('forgot_field');
+
+ echo << a:contains("$txt")').
+ before(link);
+});
+js;
+
+ exit(0);
+ }
+
+ elseif (gps('name') == 'pop')
+ {
+ $lang_check_leave = upm_file_popper_gTxt('check_leave');
+
+ echo << 'Attach',
+ 'attach_file' => 'Attach File',
+ 'check_leave' => 'You have made changes to the current post which you have not saved. Continue without saving?',
+ 'description_for' => 'Description for',
+ 'failed' => 'Insert failed.',
+ 'file_selector' => 'File Selector',
+ 'forgot_field' => 'You forgot to define the custom field for upm_file/upm_file_popper to use. Ensure that you have a custom field available, and that you have upm_file installed and activated, then visit Extensions > upm_file.',
+ 'no_description' => 'No description has been defined for this file.',
+ 'packet_custom_field' => 'Packet Custom Field',
+ 'return' => 'Return to editing the post?',
+ 'success' => 'Success.',
+ 'view_all' => 'View All'
+ );
+
+ return strtr($lang[$var], $atts);
+ }
diff --git a/upm_file_popper-0.2.2.txt b/upm_file_popper-0.2.2.txt
new file mode 100644
index 0000000..473f01a
--- /dev/null
+++ b/upm_file_popper-0.2.2.txt
@@ -0,0 +1,327 @@
+# upm_file_popper v.0.2.2
+# An easy-to-use file picker, for use with upm_file.
+
+# Mary Fredborg
+# http://utterplush.com/txp-plugins/upm_file_popper
+
+# ..........................................................................
+# A plugin for Textpattern
+# http://textpattern.com/
+#
+# Adding Plugins to Your Textpattern Installation
+# http://textpattern.net/wiki/index.php?title=Intermediate_Weblog_Model#Adding_Plugins_to_Your_Textpattern_Installation
+# ..........................................................................
+
+YToxMTp7czo0OiJuYW1lIjtzOjE1OiJ1cG1fZmlsZV9wb3BwZXIiO3M6MTE6ImRlc2NyaXB0
+aW9uIjtzOjUwOiJBbiBlYXN5LXRvLXVzZSBmaWxlIHBpY2tlciwgZm9yIHVzZSB3aXRoIHVw
+bV9maWxlLiI7czo3OiJ2ZXJzaW9uIjtzOjU6IjAuMi4yIjtzOjQ6InR5cGUiO2k6MTtzOjY6
+ImF1dGhvciI7czoxMzoiTWFyeSBGcmVkYm9yZyI7czoxMDoiYXV0aG9yX3VyaSI7czo0OToi
+aHR0cDovL3V0dGVycGx1c2guY29tL3R4cC1wbHVnaW5zL3VwbV9maWxlX3BvcHBlciI7czo0
+OiJjb2RlIjtzOjE1ODk2OiJpZiAodHhwaW50ZXJmYWNlID09ICdhZG1pbicpCgl7CgkJYWRk
+X3ByaXZzKCd1cG1fZmlsZV9wb3BwZXInLCAnMSwyLDMsNCw1Jyk7CgkJcmVnaXN0ZXJfY2Fs
+bGJhY2soJ3VwbV9maWxlX3BvcHBlcicsICd1cG1fZmlsZV9wb3BwZXInKTsKCgkJYWRkX3By
+aXZzKCd1cG1fZmlsZV9wb3BwZXJfbGluaycsICcxLDIsMyw0LDUnKTsKCQlyZWdpc3Rlcl9j
+YWxsYmFjaygndXBtX2ZpbGVfcG9wcGVyX2xpbmsnLCAnYXJ0aWNsZScpOwoKCQlhZGRfcHJp
+dnMoJ3VwbV9maWxlX3BvcHBlcl9qcycsICcxLDIsMyw0LDUnKTsKCQlyZWdpc3Rlcl9jYWxs
+YmFjaygndXBtX2ZpbGVfcG9wcGVyX2pzJywgJ3VwbV9maWxlX3BvcHBlcl9qcycsICcnLCAx
+KTsKCgkJYWRkX3ByaXZzKCd1cG1fZmlsZV9wb3BwZXJfaW1nJywgJzEsMiwzLDQsNScpOwoJ
+CXJlZ2lzdGVyX2NhbGxiYWNrKCd1cG1fZmlsZV9wb3BwZXJfaW1nJywgJ3VwbV9maWxlX3Bv
+cHBlcl9pbWcnLCAnJywgMSk7Cgl9CgovLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0t
+LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCgoJZnVuY3Rpb24gdXBtX2ZpbGVf
+cG9wcGVyKCkKCXsKCQlnbG9iYWwgJHN0ZXAsICRwcmVmczsKCgkJaWYgKCRzdGVwID09ICd1
+cG1fZmlsZV9wb3BwZXJfY2hhbmdlX3BhZ2VieScpCgkJewoJCQlldmVudF9jaGFuZ2VfcGFn
+ZWJ5KCdmaWxlJyk7CgkJCSRHTE9CQUxTWydwcmVmcyddID0gZ2V0X3ByZWZzKCk7CgkJfQoK
+CQl1cG1fZmlsZV9wb3BwZXJfbGlzdCgpOwoJfQoKLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0t
+LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQoKCWZ1bmN0aW9uIHVw
+bV9maWxlX3BvcHBlcl9saXN0KCkKCXsKCQlnbG9iYWwgJGZpbGVfYmFzZV9wYXRoLCAkcHJl
+ZnM7CgoJCXBhZ2V0b3AodXBtX2ZpbGVfcG9wcGVyX2dUeHQoJ2ZpbGVfc2VsZWN0b3InKSk7
+CgoJZWNobyA8PDxjc3MKPHN0eWxlIHR5cGU9InRleHQvY3NzIj4KPCEtLQpsYWJlbCB7CmN1
+cnNvcjogcG9pbnRlcjsKY29sb3I6ICMwMDA7Cn0KCmltZyB7CmJvcmRlcjogbm9uZTsKfQoK
+dWwgewptYXJnaW46IDA7CnBhZGRpbmc6IDA7Cmxpc3Qtc3R5bGU6IG5vbmU7Cn0KCmxpIHsK
+bWFyZ2luOiAwIDAgMnB4IDA7CnBhZGRpbmc6IDA7Cn0KCnAgewptYXJnaW46IDVweCAwOwpw
+YWRkaW5nOiAwOwp9CgoucmlnaHQgewp0ZXh0LWFsaWduOiByaWdodDsKfQoKLmNlbnRlciB7
+Cm1hcmdpbjogMCBhdXRvOwp0ZXh0LWFsaWduOiBjZW50ZXI7Cn0KCiNubyB7Cm1hcmdpbi1s
+ZWZ0OiAyZW07Cn0KCiNyZXR1cm4sICNzdWNjZXNzLCAjZmFpbGVkIHsKcGFkZGluZzogMWVt
+Owp0ZXh0LWFsaWduOiBjZW50ZXI7CmJhY2tncm91bmQtY29sb3I6ICNmZmY7CmJvcmRlcjog
+NXB4IHNvbGlkICNmYzM7Cn0KLS0+Cjwvc3R5bGU+Cgo8c2NyaXB0IHR5cGU9InRleHQvamF2
+YXNjcmlwdCIgc3JjPSJpbmRleC5waHA/ZXZlbnQ9dXBtX2ZpbGVfcG9wcGVyX2pzJiMzODtu
+YW1lPXBvcCI+PC9zY3JpcHQ+CmNzczsKCgkJZXh0cmFjdChncHNhKGFycmF5KCdwYWdlJywg
+J3NvcnQnLCAnZGlyJywgJ2NyaXQnLCAnc2VhcmNoX21ldGhvZCcpKSk7CgoJCSRkaXIgPSAo
+JGRpciA9PSAnZGVzYycpID8gJ2Rlc2MnIDogJ2FzYyc7CgoJCXN3aXRjaCAoJHNvcnQpCgkJ
+ewoJCQljYXNlICdpZCc6CgkJCQkkc29ydF9zcWwgPSAiaWQgJGRpciwgZmlsZW5hbWUgYXNj
+IjsKCQkJYnJlYWs7CgoJCQljYXNlICdmaWxlbmFtZSc6CgkJCQkkc29ydF9zcWwgPSAiZmls
+ZW5hbWUgJGRpciI7CgkJCWJyZWFrOwoKCQkJY2FzZSAnZGVzY3JpcHRpb24nOgoJCQkJJHNv
+cnRfc3FsID0gJ2Rlc2NyaXB0aW9uICcuJGRpci4nLCBmaWxlbmFtZSBkZXNjJzsKCQkJYnJl
+YWs7CgoJCQljYXNlICdjYXRlZ29yeSc6CgkJCQkkc29ydF9zcWwgPSAiY2F0ZWdvcnkgJGRp
+ciwgZmlsZW5hbWUgYXNjIjsKCQkJYnJlYWs7CgoJCQljYXNlICdkb3dubG9hZHMnOgoJCQkJ
+JHNvcnRfc3FsID0gImRvd25sb2FkcyAkZGlyLCBmaWxlbmFtZSBhc2MiOwoJCQlicmVhazsK
+CgkJCWRlZmF1bHQ6CgkJCQkkZGlyID0gJ2Rlc2MnOwoJCQkJJHNvcnRfc3FsID0gImZpbGVu
+YW1lICRkaXIiOwoJCQlicmVhazsKCQl9CgoJCSRzd2l0Y2hfZGlyID0gKCRkaXIgPT0gJ2Rl
+c2MnKSA/ICdhc2MnIDogJ2Rlc2MnOwoKCQkkY3JpdGVyaWEgPSAxOwoKCQlpZiAoJHNlYXJj
+aF9tZXRob2QgYW5kICRjcml0KQoJCXsKCQkJJGNyaXRfZXNjYXBlZCA9IGRvU2xhc2goJGNy
+aXQpOwoKCQkJJGNyaXRzcWwgPSBhcnJheSgKCQkJCSdpZCcJCQkJCT0+ICJpZCA9ICckY3Jp
+dF9lc2NhcGVkJyIsCgkJCQknZmlsZW5hbWUnCQk9PiAiZmlsZW5hbWUgbGlrZSAnJSRjcml0
+X2VzY2FwZWQlJyIsCgkJCQknY2F0ZWdvcnknCQk9PiAiY2F0ZWdvcnkgbGlrZSAnJSRjcml0
+X2VzY2FwZWQlJyIsCgkJCQknZGVzY3JpcHRpb24nID0+ICJkZXNjcmlwdGlvbiBsaWtlICcl
+JGNyaXRfZXNjYXBlZCUnIgoJCQkpOwoKCQkJaWYgKGFycmF5X2tleV9leGlzdHMoJHNlYXJj
+aF9tZXRob2QsICRjcml0c3FsKSkKCQkJewoJCQkJJGNyaXRlcmlhID0gJGNyaXRzcWxbJHNl
+YXJjaF9tZXRob2RdOwoJCQkJJGxpbWl0ID0gNTAwOwoJCQl9CgoJCQllbHNlCgkJCXsKCQkJ
+CSRzZWFyY2hfbWV0aG9kID0gJyc7CgkJCQkkY3JpdCA9ICcnOwoJCQl9CgkJfQoKCQllbHNl
+CgkJewoJCQkkc2VhcmNoX21ldGhvZCA9ICcnOwoJCQkkY3JpdCA9ICcnOwoJCX0KCgkJJHRv
+dGFsID0gc2FmZV9jb3VudCgndHhwX2ZpbGUnLCAiJGNyaXRlcmlhIik7CgoJCWlmICgkdG90
+YWwgPCAxKQoJCXsKCQkJaWYgKCRjcml0ZXJpYSAhPSAxKQoJCQl7CgkJCQllY2hvIG4udXBt
+X2ZpbGVfcG9wcGVyX3NlYXJjaF9mb3JtKCRjcml0LCAkc2VhcmNoX21ldGhvZCwgJHNvcnQs
+ICRkaXIpLgoJCQkJCW4uZ3JhZihnVHh0KCdub19yZXN1bHRzX2ZvdW5kJyksICcgc3R5bGU9
+InRleHQtYWxpZ246IGNlbnRlcjsiJyk7CgkJCX0KCgkJCWVsc2UKCQkJewoJCQkJZWNobyBu
+LmdyYWYoZ1R4dCgnbm9fZmlsZXNfcmVjb3JkZWQnKSwgJyBzdHlsZT0idGV4dC1hbGlnbjog
+Y2VudGVyOyInKTsKCQkJfQoKCQkJcmV0dXJuOwoJCX0KCgkJJGxpbWl0ID0gbWF4KCRwcmVm
+c1snZmlsZV9saXN0X3BhZ2VieSddLCAxNSk7CgoJCWxpc3QoJHBhZ2UsICRvZmZzZXQsICRu
+dW1QYWdlcykgPSBwYWdlcigkdG90YWwsICRsaW1pdCwgJHBhZ2UpOwoKCQllY2hvIHVwbV9m
+aWxlX3BvcHBlcl9zZWFyY2hfZm9ybSgkY3JpdCwgJHNlYXJjaF9tZXRob2QsICRzb3J0LCAk
+ZGlyKTsKCgkJJHJzID0gc2FmZV9yb3dzX3N0YXJ0KCcqJywgJ3R4cF9maWxlJywgIiRjcml0
+ZXJpYSBvcmRlciBieSAkc29ydF9zcWwgbGltaXQgJG9mZnNldCwgJGxpbWl0Iik7CgoJCWlm
+ICgkcnMpCgkJewoJCQkkc29ydF9saW5rID0gJ3VwbV9maWxlX3BvcHBlcicuYS4nYm09dHJ1
+ZSc7CgoJCQllY2hvIHN0YXJ0VGFibGUoJ2xpc3QnKSwKCQkJCXRyKAoJCQkJCWNvbHVtbl9o
+ZWFkKCdJRCcsICdpZCcsICRzb3J0X2xpbmssIHRydWUsICRzd2l0Y2hfZGlyLCAkY3JpdCwg
+JHNlYXJjaF9tZXRob2QpLgoJCQkJCWNvbHVtbl9oZWFkKCdmaWxlX25hbWUnLCAnZmlsZW5h
+bWUnLCAkc29ydF9saW5rLCB0cnVlLAkkc3dpdGNoX2RpciwgJGNyaXQsICRzZWFyY2hfbWV0
+aG9kKS4KCQkJCQljb2x1bW5faGVhZCgnZGVzY3JpcHRpb24nLCAnZGVzY3JpcHRpb24nLCAk
+c29ydF9saW5rLCB0cnVlLCAkc3dpdGNoX2RpciwgJGNyaXQsICRzZWFyY2hfbWV0aG9kKS4K
+CQkJCQljb2x1bW5faGVhZCgnZmlsZV9jYXRlZ29yeScsICdjYXRlZ29yeScsICRzb3J0X2xp
+bmssIHRydWUsICRzd2l0Y2hfZGlyLCAkY3JpdCwgJHNlYXJjaF9tZXRob2QpLgoJCQkJCWhD
+ZWxsKCkuCgkJCQkJaENlbGwoZ1R4dCgndGFncycpKS4KCQkJCQloQ2VsbChnVHh0KCdzdGF0
+dXMnKSkuCgkJCQkJY29sdW1uX2hlYWQoJ2Rvd25sb2FkcycsICdkb3dubG9hZHMnLCAkc29y
+dF9saW5rLCB0cnVlLCAkc3dpdGNoX2RpciwgJGNyaXQsICRzZWFyY2hfbWV0aG9kKQoJCQkJ
+KTsKCgkJCXdoaWxlICgkYSA9IG5leHRSb3coJHJzKSkKCQkJewoJCQkJZXh0cmFjdCgkYSk7
+CgoJCQkJLy8gZ29kIEkgaGF0ZSBqYXZhc2NyaXB0IGluIHBocAoJCQkJJGluc2VydCA9ICc8
+YSBocmVmPSIjIiBvbmNsaWNrPSJ1cG1fZmlsZV9wb3BwZXJfYXR0YWNoRmlsZSgnLmNocigz
+OSkuJGlkLmNocigzOSkuJyk7IHJldHVybiBmYWxzZTsiPjxpbWcgc3JjPSJpbmRleC5waHA/
+ZXZlbnQ9dXBtX2ZpbGVfcG9wcGVyX2ltZyIgd2lkdGg9IjE2cHgiIGhlaWdodD0iMTZweCIg
+YWx0PSInLnVwbV9maWxlX3BvcHBlcl9nVHh0KCdhdHRhY2hfZmlsZScpLiciIHRpdGxlPSIn
+LnVwbV9maWxlX3BvcHBlcl9nVHh0KCdhdHRhY2hfZmlsZScpLiciIC8+PC9hPic7CgoJCQkJ
+JHRhZ191cmwgPSAnP2V2ZW50PXRhZycuYS4ndGFnX25hbWU9ZmlsZV9kb3dubG9hZF9saW5r
+Jy5hLidpZD0nLiRpZC5hLidkZXNjcmlwdGlvbj0nLnVybGVuY29kZSgkZGVzY3JpcHRpb24p
+LgoJCQkJCWEuJ2ZpbGVuYW1lPScudXJsZW5jb2RlKCRmaWxlbmFtZSk7CgoJCQkJJGZpbGVf
+ZXhpc3RzID0gZmlsZV9leGlzdHMoYnVpbGRfZmlsZV9wYXRoKCRmaWxlX2Jhc2VfcGF0aCwg
+JGZpbGVuYW1lKSk7CgoJCQkJJHN0YXR1cyA9ICgkZmlsZV9leGlzdHMpID8KCQkJCQknPHNw
+YW4gY2xhc3M9Im9rIj4nLmdUeHQoJ2ZpbGVfc3RhdHVzX29rJykuJzwvc3Bhbj4nIDoKCQkJ
+CQknPHNwYW4gY2xhc3M9Im5vdC1vayI+Jy5nVHh0KCdmaWxlX3N0YXR1c19taXNzaW5nJyku
+Jzwvc3Bhbj4nOwoKCQkJCWlmICghaXNzZXQoJGRvd25sb2FkcykpCgkJCQl7CgkJCQkJc2Fm
+ZV9hbHRlcigndHhwX2ZpbGUnLCAiQUREIGRvd25sb2FkcyBJTlQgREVGQVVMVCAnMCcgTk9U
+IE5VTEwiKTsKCQkJCQkkZG93bmxvYWRzID0gMDsKCQkJCX0KCgkJCQllbHNlaWYgKGVtcHR5
+KCRkb3dubG9hZHMpKQoJCQkJewoJCQkJCSRkb3dubG9hZHMgPSAnMCc7CgkJCQl9CgoKCQkJ
+CWVjaG8gbi5uLnRyKAoKCQkJCQluLnRkKCRpZCkuCgoJCQkJCXRkKCc8YSBocmVmPSIjIiBv
+bmNsaWNrPSJ1cG1fZmlsZV9wb3BwZXJfd2FybkVkaXRGaWxlKCcuJGlkLicpOyByZXR1cm4g
+ZmFsc2U7Ij4nLiRmaWxlbmFtZS4nPC9hPicsIDEyNSkuCgoJCQkJCXRkKCRkZXNjcmlwdGlv
+biwgMTUwKS4KCQkJCQl0ZCgkY2F0ZWdvcnksIDkwKS4KCgkJCQkJdGQoJGluc2VydCkuCgoJ
+CQkJCXRkKAoJCQkJCQluLic8dWw+Jy4KCQkJCQkJbi50Lic8bGk+PGEgdGFyZ2V0PSJfYmxh
+bmsiIGhyZWY9IicuJHRhZ191cmwuYS4ndHlwZT10ZXh0aWxlIiBvbmNsaWNrPSJwb3BXaW4o
+dGhpcy5ocmVmLCA0MDAsIDI1MCk7IHJldHVybiBmYWxzZTsiPlRleHRpbGU8L2E+PC9saT4n
+LgoJCQkJCQluLnQuJzxsaT48YSB0YXJnZXQ9Il9ibGFuayIgaHJlZj0iJy4kdGFnX3VybC5h
+Lid0eXBlPXRleHRwYXR0ZXJuIiBvbmNsaWNrPSJwb3BXaW4odGhpcy5ocmVmLCA0MDAsIDI1
+MCk7IHJldHVybiBmYWxzZTsiPlRleHRwYXR0ZXJuPC9hPjwvbGk+Jy4KCQkJCQkJbi50Lic8
+bGk+PGEgdGFyZ2V0PSJfYmxhbmsiIGhyZWY9IicuJHRhZ191cmwuYS4ndHlwZT14aHRtbCIg
+b25jbGljaz0icG9wV2luKHRoaXMuaHJlZiwgNDAwLCAyNTApOyByZXR1cm4gZmFsc2U7Ij5Y
+SFRNTDwvYT48L2xpPicuCgkJCQkJCW4uJzwvdWw+JwoJCQkJCSwgNzUpLgoKCQkJCQl0ZCgk
+c3RhdHVzLCA0NSkuCgoJCQkJCXRkKAoJCQkJCQkoJGRvd25sb2FkcyA9PSAnMCcgPyBnVHh0
+KCdub25lJykgOiAkZG93bmxvYWRzKQoJCQkJCSwgMjUpCgkJCQkpOwoJCQl9CgoJCQllY2hv
+IGVuZFRhYmxlKCkuCgoJCQkJbmF2X2Zvcm0oJ3VwbV9maWxlX3BvcHBlcicsICRwYWdlLCAk
+bnVtUGFnZXMsICRzb3J0LCAkZGlyLCAkY3JpdCwgJHNlYXJjaF9tZXRob2QpLgoKCQkJCXVw
+bV9maWxlX3BvcHBlcl9wYWdlYnlfZm9ybSgpLgoKCQkJCW4udGFnKAoJCQkJCW4uZ3JhZih1
+cG1fZmlsZV9wb3BwZXJfZ1R4dCgncmV0dXJuJykpLgoJCQkJCW4uZ3JhZignPGEgaWQ9Inll
+cyIgaHJlZj0iIyIgb25jbGljaz0idXBtX2ZpbGVfcG9wcGVyX2dvQmFjayh0aGlzLmhyZWYp
+OyByZXR1cm4gZmFsc2U7Ij4nLmdUeHQoJ3llcycpLic8L2E+LicuCgkJCQkJCScgPGEgaWQ9
+Im5vIiBocmVmPSIjIiBvbmNsaWNrPSJ1cG1fZmlsZV9wb3BwZXJfZG9uZShcJ3JldHVyblwn
+KTsgcmV0dXJuIGZhbHNlOyI+Jy5nVHh0KCdubycpLic8L2E+LicpCgkJCQksICdkaXYnLAkn
+IGlkPSJyZXR1cm4iIHN0eWxlPSJkaXNwbGF5OiBub25lOyB3aWR0aDogMjAwcHg7IGhlaWdo
+dDogNzVweDsiJykuCgoJCQkJbi5ncmFmKHVwbV9maWxlX3BvcHBlcl9nVHh0KCdzdWNjZXNz
+JyksICcgaWQ9InN1Y2Nlc3MiIHN0eWxlPSJkaXNwbGF5OiBub25lOyB3aWR0aDogMTUwcHg7
+IGhlaWdodDogMzVweDsiJykuCgkJCQluLmdyYWYodXBtX2ZpbGVfcG9wcGVyX2dUeHQoJ2Zh
+aWxlZCcpLCAnIGlkPSJmYWlsZWQiIHN0eWxlPSJkaXNwbGF5OiBub25lOyB3aWR0aDogMTUw
+cHg7IGhlaWdodDogMzVweDsiJyk7CgkJfQoJfQoKLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0t
+LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQoKCWZ1bmN0aW9uIHVw
+bV9maWxlX3BvcHBlcl9zZWFyY2hfZm9ybSgkY3JpdCwgJG1ldGhvZCwgJHNvcnQsICRkaXIp
+Cgl7CgkJJGRlZmF1bHRfbWV0aG9kID0gJ2ZpbGVuYW1lJzsKCgkJJG1ldGhvZCA9ICgkbWV0
+aG9kKSA/ICRtZXRob2QgOiAkZGVmYXVsdF9tZXRob2Q7CgoJCSRtZXRob2RzID0JYXJyYXko
+CgkJCSdpZCcJCQkJCT0+IGdUeHQoJ2lkJyksCgkJCSdmaWxlbmFtZScJCT0+IGdUeHQoJ2Zp
+bGVfbmFtZScpLAoJCQknZGVzY3JpcHRpb24nID0+IGdUeHQoJ2Rlc2NyaXB0aW9uJyksCgkJ
+CSdjYXRlZ29yeScJCT0+IGdUeHQoJ2ZpbGVfY2F0ZWdvcnknKQoJCSk7CgoJCXJldHVybiBu
+Lm4uJzxmb3JtIG1ldGhvZD0iZ2V0IiBhY3Rpb249ImluZGV4LnBocCIgc3R5bGU9Im1hcmdp
+bjogYXV0bzsgdGV4dC1hbGlnbjogY2VudGVyOyI+Jy4KCQkJZ3JhZigKCQkJCSc8bGFiZWwg
+Zm9yPSJ1cG0tZmlsZS1wb3BwZXItc2VhcmNoIj4nLmdUeHQoJ3NlYXJjaCcpLic8L2xhYmVs
+Picuc3AuCgkJCQlzZWxlY3RJbnB1dCgnc2VhcmNoX21ldGhvZCcsICRtZXRob2RzLCAkbWV0
+aG9kLCAnJywgJycsICd1cG0tZmlsZS1wb3BwZXItc2VhcmNoJykuc3AuCgkJCQlmSW5wdXQo
+J3RleHQnLCAnY3JpdCcsICRjcml0LCAnZWRpdCcsICcnLCAnJywgJzE1JykuCgkJCQllSW5w
+dXQoJ3VwbV9maWxlX3BvcHBlcicpLgoJCQkJaElucHV0KCdibScsJ3RydWUnKS4KCQkJCWZJ
+bnB1dCgnc3VibWl0JywgJ3NlYXJjaCcsIGdUeHQoJ2dvJyksICdzbWFsbGVyYm94JykKCQkJ
+KS4KCgkJCSgkY3JpdCA/IG4uZ3JhZignPGEgaHJlZj0iP2V2ZW50PXVwbV9maWxlX3BvcHBl
+cicuYS4nYm09dHJ1ZSI+Jy51cG1fZmlsZV9wb3BwZXJfZ1R4dCgndmlld19hbGwnKS4nPC9h
+PicpIDogJycpLgoKCQluLic8L2Zvcm0+JzsKCX0KCi8vIC0tLS0tLS0tLS0tLS0tLS0tLS0t
+LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KCglmdW5jdGlvbiB1
+cG1fZmlsZV9wb3BwZXJfcGFnZWJ5X2Zvcm0oKQoJewoJCWdsb2JhbCAkcHJlZnM7CgoJCSR2
+YWxzID0gYXJyYXkoCgkJCTE1CT0+IDE1LAoJCQkyNQk9PiAyNSwKCQkJNTAJPT4gNTAsCgkJ
+CTEwMCA9PiAxMDAKCQkpOwoKCQkkc2VsZWN0X3BhZ2UgPSBzZWxlY3RJbnB1dCgncXR5Jywg
+JHZhbHMsICRwcmVmc1snZmlsZV9saXN0X3BhZ2VieSddLCAnJywgMSk7CgoJCS8vIHByb3Bl
+ciBsb2NhbGlzYXRpb24KCQkkcGFnZSA9IHN0cl9yZXBsYWNlKCd7cGFnZX0nLCAkc2VsZWN0
+X3BhZ2UsIGdUeHQoJ3ZpZXdfcGVyX3BhZ2UnKSk7CgoJCXJldHVybiBmb3JtKAoJCQknPGRp
+diBzdHlsZT0ibWFyZ2luOiBhdXRvOyB0ZXh0LWFsaWduOiBjZW50ZXI7Ij4nLgoJCQkJJHBh
+Z2UuCgkJCQllSW5wdXQoJ3VwbV9maWxlX3BvcHBlcicpLgoJCQkJc0lucHV0KCd1cG1fZmls
+ZV9wb3BwZXJfY2hhbmdlX3BhZ2VieScpLgoJCQkJaElucHV0KCdibScsICcxJykuCgkJCQkn
+PG5vc2NyaXB0PiA8aW5wdXQgdHlwZT0ic3VibWl0IiB2YWx1ZT0iJy5nVHh0KCdnbycpLici
+IGNsYXNzPSJzbWFsbGVyYm94IiAvPjwvbm9zY3JpcHQ+Jy4KCQkJJzwvZGl2PicKCQkpOwoJ
+fQoKLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0t
+LS0tLS0tLS0tLS0tLQoKCWZ1bmN0aW9uIHVwbV9maWxlX3BvcHBlcl9saW5rKCkKCXsKCQkk
+dmlldyA9IGdwcygndmlldycpOwoKCQlpZiAoJHZpZXcgPT0gJ3RleHQnIG9yIGVtcHR5KCR2
+aWV3KSkKCQl7CgkJCWVjaG8gPDw8Zm9ybQoKPGZvcm0gYWN0aW9uPSIiPgo8aW5wdXQgdHlw
+ZT0iaGlkZGVuIiBpZD0idXBtX2ZpbGVfcG9wcGVyX3N0YXJ0IiB2YWx1ZT0iIj4KPC9mb3Jt
+PgoKPHNjcmlwdCB0eXBlPSJ0ZXh0L2phdmFzY3JpcHQiIHNyYz0iaW5kZXgucGhwP2V2ZW50
+PXVwbV9maWxlX3BvcHBlcl9qcyYjMzg7bmFtZT1saW5rIj48L3NjcmlwdD4KZm9ybTsKCQl9
+Cgl9CgovLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0t
+LS0tLS0tLS0tLS0tLS0tCgoJZnVuY3Rpb24gdXBtX2ZpbGVfcG9wcGVyX2pzKCkKCXsKCQln
+bG9iYWwgJHByZWZzOwoKCQl3aGlsZSAoQG9iX2VuZF9jbGVhbigpKTsKCgkJaGVhZGVyKCJD
+b250ZW50LXR5cGU6IHRleHQvamF2YXNjcmlwdCIpOwoKCQlpZiAoZW1wdHkoJHByZWZzWyd1
+cG1fZmlsZV9maWVsZCddKSkKCQl7CgkJCSRsYW5nX2ZvcmdvdF9maWVsZCA9IHVwbV9maWxl
+X3BvcHBlcl9nVHh0KCdmb3Jnb3RfZmllbGQnKTsKCgkJCWVjaG8gPDw8anMKLyoKdXBtX2Zp
+bGVfcG9wcGVyIC0gY3VzdG9tIGZpZWxkIGhhcyBub3QgYmVlbiBkZWZpbmVkCiovCgokKGRv
+Y3VtZW50KS5yZWFkeShmdW5jdGlvbigpIHsKCWFsZXJ0KCckbGFuZ19mb3Jnb3RfZmllbGQn
+KTsKfSk7CmpzOwoJCQlleGl0KDApOwoJCX0KCgkJZWxzZQoJCXsKCQkJJHVwbV9maWxlX2Zp
+ZWxkID0gIWVtcHR5KCRwcmVmc1sndXBtX2ZpbGVfZmllbGQnXSkgPyAkcHJlZnNbJ3VwbV9m
+aWxlX2ZpZWxkJ10gOiAnJzsKCQkJJHVwbV9maWxlX2ZpZWxkID0gc3RyX3JlcGxhY2UoJ18n
+LCAnLScsICR1cG1fZmlsZV9maWVsZCk7CgkJfQoKCQlpZiAoZ3BzKCduYW1lJykgPT0gJ2xp
+bmsnKQoJCXsKCQkJJHR4dCA9IGdUeHQoJ2FkdmFuY2VkX29wdGlvbnMnKTsKCgkJCSRsYW5n
+X2F0dGFjaF9maWxlID0gdXBtX2ZpbGVfcG9wcGVyX2dUeHQoJ2F0dGFjaF9maWxlJyk7CgoJ
+CQllY2hvIDw8PGpzCi8qCnVwbV9maWxlX3BvcHBlciAtIGFydGljbGUgd2luZG93CiovCgok
+KGRvY3VtZW50KS5yZWFkeShmdW5jdGlvbigpIHsKCS8vIC0tLS0tLS0tLS0tLS0tLS0tLS0t
+LS0tLS0tLS0tLQoJLy8gc2V0dXAgYXJ0aWNsZSBlZGl0IHRyYWNraW5nCgoJJCgnI3VwbV9m
+aWxlX3BvcHBlcl9zdGFydCcpLnZhbCggJCgnYm9keScpLnZhbCgpICk7CgoJLy8gLS0tLS0t
+LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCgkvLyBjcmVhdGUgYW5kIGluc2VydCBwb3B1cCBs
+aW5rCgoJdmFyIHcgPSA1NzU7Cgl2YXIgaCA9IDM3NTsKCgl2YXIgdCA9IChzY3JlZW4uaGVp
+Z2h0KSA/IChzY3JlZW4uaGVpZ2h0IC0gaCkgLyAyIDogMDsKCXZhciBsID0gKHNjcmVlbi53
+aWR0aCkgPyAoc2NyZWVuLndpZHRoIC0gdykgLyAyIDogMDsKCgl2YXIgYSA9ICQoZG9jdW1l
+bnQuY3JlYXRlRWxlbWVudCgnYScpKS4KCQl0ZXh0KCckbGFuZ19hdHRhY2hfZmlsZScpLgoJ
+CWF0dHIoewoJCQl0YXJnZXQ6ICdfYmxhbmsnLAoJCQlocmVmOiAnP2V2ZW50PXVwbV9maWxl
+X3BvcHBlclx1MDAyNmJtPTEnCgkJfSkuCgkJY2xpY2soZnVuY3Rpb24gKCkgewoJCQl2YXIg
+dXBtX2ZpbGVfcG9wcGVyID0gd2luZG93Lm9wZW4odGhpcy5ocmVmLCAndXBtX2ZpbGVfcG9w
+cGVyJywgJ3RvcCA9ICcrdCsnLCBsZWZ0ID0gJytsKycsIHdpZHRoID0gJyt3KycsIGhlaWdo
+dCA9ICcraCsnLCB0b29sYmFyID0gbm8sIGxvY2F0aW9uID0gbm8sIGRpcmVjdG9yaWVzID0g
+bm8sIHN0YXR1cyA9IHllcywgbWVudWJhciA9IG5vLCBzY3JvbGxiYXJzID0geWVzLCBjb3B5
+aGlzdG9yeSA9IG5vLCByZXNpemFibGUgPSB5ZXMnKTsKCQkJdXBtX2ZpbGVfcG9wcGVyLmZv
+Y3VzKCk7CgkJCXJldHVybiBmYWxzZTsKCQl9KTsKCgl2YXIgbGluayA9ICQoZG9jdW1lbnQu
+Y3JlYXRlRWxlbWVudCgnaDMnKSkuCgkJYWRkQ2xhc3MoJ3BsYWluJykuCgkJYXBwZW5kKGEp
+OwoKCSQoJ2gzLnBsYWluID4gYTpjb250YWlucygiJHR4dCIpJykuCgkJYmVmb3JlKGxpbmsp
+Owp9KTsKanM7CgoJCWV4aXQoMCk7Cgl9CgoJZWxzZWlmIChncHMoJ25hbWUnKSA9PSAncG9w
+JykKCXsKCQkkbGFuZ19jaGVja19sZWF2ZSA9IHVwbV9maWxlX3BvcHBlcl9nVHh0KCdjaGVj
+a19sZWF2ZScpOwoKCQllY2hvIDw8PGpzCi8qCnVwbV9maWxlX3BvcHBlciAtIHBvcHVwIHdp
+bmRvdwoqLwoKCWZ1bmN0aW9uIHVwbV9maWxlX3BvcHBlcl9hdHRhY2hGaWxlKGlkKQoJewoJ
+CXZhciBmaWVsZCA9ICQoJyMkdXBtX2ZpbGVfZmllbGQnLCB3aW5kb3cub3BlbmVyLmRvY3Vt
+ZW50KS52YWwoKTsKCgkJaWYgKCQoJ2Zvcm1bbmFtZT0iYXJ0aWNsZSJdJywgd2luZG93Lm9w
+ZW5lcikpCgkJewoJCQlpZiAoZmllbGQgPT0gJycpCgkJCXsKCQkJCSQoJyMkdXBtX2ZpbGVf
+ZmllbGQnLCB3aW5kb3cub3BlbmVyLmRvY3VtZW50KS52YWwoaWQpOwoJCQkJcmV0dXJuIHVw
+bV9maWxlX3BvcHBlcl9zaG93TXNnKCdzdWNjZXNzJyk7CgkJCX0KCgkJCWVsc2UKCQkJewoJ
+CQkJJCgnIyR1cG1fZmlsZV9maWVsZCcsIHdpbmRvdy5vcGVuZXIuZG9jdW1lbnQpLnZhbChm
+aWVsZCArICcsJyArIGlkKTsKCQkJCXJldHVybiB1cG1fZmlsZV9wb3BwZXJfc2hvd01zZygn
+c3VjY2VzcycpOwoJCQl9CgkJfQoKCQlyZXR1cm4gdXBtX2ZpbGVfcG9wcGVyX3Nob3dNc2co
+J2ZhaWxlZCcpOwoJfQoKLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0t
+LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQoKCWZ1bmN0aW9uIHVwbV9maWxlX3BvcHBlcl93
+YXJuRWRpdEZpbGUoaWQpCgl7CgkJaWYgKCQoJyNib2R5Jywgd2luZG93Lm9wZW5lci5kb2N1
+bWVudCkudmFsKCkgIT0gJCgnI3VwbV9maWxlX3BvcHBlcl9zdGFydCcsIHdpbmRvdy5vcGVu
+ZXIuZG9jdW1lbnQpLnZhbCgpKQoJCXsKCQkJdmFyIGNoZWNrID0gY29uZmlybSgnJGxhbmdf
+Y2hlY2tfbGVhdmUnKTsKCgkJCWlmIChjaGVjaykKCQkJewoJCQkJdXBtX2ZpbGVfcG9wcGVy
+X2dvRWRpdEZpbGUoaWQpOwoJCQl9CgkJfQoKCQllbHNlCgkJewoJCQl1cG1fZmlsZV9wb3Bw
+ZXJfZ29FZGl0RmlsZShpZCk7CgkJfQoJfQoKLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0t
+LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQoKCWZ1bmN0aW9uIHVwbV9m
+aWxlX3BvcHBlcl9nb0VkaXRGaWxlKGlkKQoJewoJCXdpbmRvdy5vcGVuZXIuZm9jdXMoKTsK
+CgkJaWYgKCQoJ2lucHV0W25hbWU9InN0ZXAiXScsIHdpbmRvdy5vcGVuZXIuZG9jdW1lbnQp
+LnZhbCgpICE9ICdjcmVhdGUnKQoJCXsKCQkJJCgnI3llcycpLmF0dHIoJ2hyZWYnLCB3aW5k
+b3cub3BlbmVyLmRvY3VtZW50LmxvY2F0aW9uKTsKCQkJdXBtX2ZpbGVfcG9wcGVyX3Nob3dN
+c2coJ3JldHVybicpOwoJCX0KCgkJd2luZG93Lm9wZW5lci5kb2N1bWVudC5sb2NhdGlvbiA9
+ICc/ZXZlbnQ9ZmlsZVx1MDAyNnN0ZXA9ZmlsZV9lZGl0XHUwMDI2aWQ9JytpZDsKCX0KCi8v
+IC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0t
+LS0tLS0tLS0KCglmdW5jdGlvbiB1cG1fZmlsZV9wb3BwZXJfZ29CYWNrKHVybCkKCXsKCQl3
+aW5kb3cub3BlbmVyLmZvY3VzKCk7CgoJCXVwbV9maWxlX3BvcHBlcl9kb25lKCdyZXR1cm4n
+KTsKCgkJd2luZG93Lm9wZW5lci5kb2N1bWVudC5sb2NhdGlvbiA9IHVybDsKCX0KCi8vIC0t
+LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0t
+LS0tLS0KCglmdW5jdGlvbiB1cG1fZmlsZV9wb3BwZXJfc2hvd01zZyhpZCkKCXsKCQl2YXIg
+bXNnID0gJCgnIycraWQpOwoKCQltc2cuY3NzKHsKCQkJcG9zaXRpb246ICdhYnNvbHV0ZScs
+CgkJCXRvcDoJCQkxMDAgKyB1cG1fZmlsZV9wb3BwZXJfc2Nyb2xsVG9wKCkgKyAncHgnLAoJ
+CQlsZWZ0OgkJCSggKHVwbV9maWxlX3BvcHBlcl9wYWdlV2lkdGgoKSAvIDIpIC0gKHBhcnNl
+SW50KG1zZy5jc3MoJ3dpZHRoJykpIC8gMikgKSArIHVwbV9maWxlX3BvcHBlcl9zY3JvbGxM
+ZWZ0KCkgKyAncHgnLAoJCQlkaXNwbGF5OgknYmxvY2snCgkJfSk7CgoJCWlmIChpZCAhPSAn
+cmV0dXJuJykKCQl7CgkJCXNldFRpbWVvdXQoInVwbV9maWxlX3BvcHBlcl9kb25lKCciK2lk
+KyInKSIsIDEwMDApOwoJCX0KCX0KCi8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0t
+LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KCglmdW5jdGlvbiB1cG1fZmlsZV9w
+b3BwZXJfZG9uZShpZCkKCXsKCQkkKCcjJytpZCkuY3NzKCdkaXNwbGF5JywgJ25vbmUnKTsK
+CX0KCi8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0t
+LS0tLS0tLS0tLS0tLS0KCglmdW5jdGlvbiB1cG1fZmlsZV9wb3BwZXJfcGFnZVdpZHRoKCkK
+CXsKCQlpZiAoc2VsZi5pbm5lcldpZHRoKQoJCXsKCQkJcmV0dXJuIHNlbGYuaW5uZXJXaWR0
+aDsKCQl9CgoJCWVsc2UgaWYgKGRvY3VtZW50LmRvY3VtZW50RWxlbWVudCAmJiBkb2N1bWVu
+dC5kb2N1bWVudEVsZW1lbnQuY2xpZW50V2lkdGgpCgkJewoJCQlyZXR1cm4gZG9jdW1lbnQu
+ZG9jdW1lbnRFbGVtZW50LmNsaWVudFdpZHRoOwoJCX0KCgkJcmV0dXJuIDA7Cgl9CgovLyAt
+LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0t
+LS0tLS0tCgoJZnVuY3Rpb24gdXBtX2ZpbGVfcG9wcGVyX3Njcm9sbFRvcCgpCgl7CgkJaWYg
+KHNlbGYucGFnZVlPZmZzZXQpCgkJewoJCQlyZXR1cm4gc2VsZi5wYWdlWU9mZnNldDsKCQl9
+CgoJCWVsc2UgaWYgKGRvY3VtZW50LmRvY3VtZW50RWxlbWVudCAmJiBkb2N1bWVudC5kb2N1
+bWVudEVsZW1lbnQuc2Nyb2xsVG9wKQoJCXsKCQkJcmV0dXJuIGRvY3VtZW50LmRvY3VtZW50
+RWxlbWVudC5zY3JvbGxUb3A7CgkJfQoKCQlyZXR1cm4gMDsKCX0KCi8vIC0tLS0tLS0tLS0t
+LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KCglm
+dW5jdGlvbiB1cG1fZmlsZV9wb3BwZXJfc2Nyb2xsTGVmdCgpCgl7CgkJaWYgKHNlbGYucGFn
+ZVlPZmZzZXQpCgkJewoJCQlyZXR1cm4gc2VsZi5wYWdlWE9mZnNldDsKCQl9CgoJCWVsc2Ug
+aWYgKGRvY3VtZW50LmRvY3VtZW50RWxlbWVudCAmJiBkb2N1bWVudC5kb2N1bWVudEVsZW1l
+bnQuc2Nyb2xsVG9wKQoJCXsKCQkJcmV0dXJuIGRvY3VtZW50LmRvY3VtZW50RWxlbWVudC5z
+Y3JvbGxMZWZ0OwoJCX0KCgkJcmV0dXJuIDA7Cgl9CmpzOwoKCQlleGl0KDApOwoJfQp9Cgov
+LyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0t
+LS0tLS0tLS0tCgoJZnVuY3Rpb24gdXBtX2ZpbGVfcG9wcGVyX2ltZygpCgl7CgkJd2hpbGUg
+KEBvYl9lbmRfY2xlYW4oKSk7CgoJCWhlYWRlcigiQ29udGVudC10eXBlOiBpbWFnZS9naWYi
+KTsKCgkJZWNobyBiYXNlNjRfZGVjb2RlKCdpVkJPUncwS0dnb0FBQUFOU1VoRVVnQUFBQkFB
+QUFBUUNBWUFBQUFmOC85aEFBQUFCR2RCVFVFQUFLL0lOd1dLNicuCgkJCSdRQUFBQmwwUlZo
+MFUyOW1kSGRoY21VQVFXUnZZbVVnU1cxaFoyVlNaV0ZrZVhISlpUd0FBQUp2U1VSQlZEakxw
+WlByUzVOaEdJZjlXN1l2QllPJy4KCQkJJ2tobGtvcUNrbFdDaHYyV3lLaWs3YmxuTnJpczcy
+Ymk2ZHVzMERMWjBURHhXMW9kdG9wRHM0RDhNRFp1TFUwa1hxNjFDaWpTSUlhc092djk0VlQn
+LgoJCQknVWZMaUI3NGZYbmd1cDdudnJudkpBQkovNVBmTG5UVGRjd09qNFJzZFltbzVnbEJX
+UDZpT3R6d3ZJS1NXc3RJMFdneDgwU0JibHBLdEU5S1FzLycuCgkJCSdXZTdFYVdvVC84d2JX
+UDYxZ01tQ0gwbE1Edm9rVDRqMjVUaVFVL0lURmtlazlPdzYrN1dIMmd3c21haENQZHd5dzc1
+dXc5SEVPMmdVWlNrZnlJJy4KCQkJJzl6QlBDSk9vSjJTTW1nNDZONjFZTy9yTm9hMzlYaTQx
+b0Z1WHlzTWZoMzYvRnAwYjdiQWZXQUg2UkdpMEhnbFdOQ2J6WWdKYUZqUnY2ekd1eSsnLgoJ
+CQknYjlJdDk2TjNTUXZOS2lWOUh2U2FEZkZFSXhYSXRuUHMyM0J6SlFkNkRERVZNME9Lc29W
+d0JHLzFWTXpwWFZXaGJrVU0ySzRvSkJEWXVHbWJLSScuCgkJCSdKMHF4c0FiSGZSTHpiamNu
+VWJGQklweC9xSDN2UXY5YjNVMDNJUS9IZkZrRVJUemZGajh3OGpTcFI3R0JFMTIzdUZFWUF6
+YURSSXFYLzJKQXRKJy4KCQkJJ2JEYXQvQ09rZDdDTkJ2YTJjTXZxME1HeHAwUFJTQ1BGOEJY
+aldHM0ZnTkhjOVhQVDcxT2p5M3NNRmRmSlJDZUt4RXNWdEt3Rkh3QUxaZkNVazMnLgoJCQkn
+dElmTlI4WGlKd2MxTG1MNGRnMTQxSlBLdGozV1VkTkZKcUxHRlZQQzRPa1I0QnhhalRXc0No
+WTY0d21Dbk14c1dQQ0hjdXRLQnhNVnA1bXhBMScuCgkJCSdTK2FNQ29tVG9hcVRSVVFrbkxU
+SDYya0hPVkVFK1ZRbmphaHNjTkN5MGNNQldzU0kwVENRY1pjNUFMa0VZY2tMNUE1bm9XU0Jo
+Zm0yQWVjTUFqJy4KCQkJJ2JjUldWMHBVVGgwSEU2NFROZjBtY3pjbm5ReXUvTWlsYUZKQ2Fl
+MW53MmZiejFEblZPeHlHVGxLZVpmdC9GZjh4MUJSc3NmQUNqVHdRQUFBQUInLgoJCQknSlJV
+NUVya0pnZ2c9PScpOwoKCQlleGl0KDApOwoJfQoKLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0t
+LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQoKCWZ1bmN0aW9uIHVw
+bV9maWxlX3BvcHBlcl9nVHh0KCR2YXIsICRhdHRzID0gYXJyYXkoKSkKCXsKCQkkbGFuZyA9
+IGFycmF5KAoJCQknYXR0YWNoJyAgICAgICAgICAgICAgPT4gJ0F0dGFjaCcsCgkJCSdhdHRh
+Y2hfZmlsZScgICAgICAgICA9PiAnQXR0YWNoIEZpbGUnLAoJCQknY2hlY2tfbGVhdmUnICAg
+ICAgICAgPT4gJ1lvdSBoYXZlIG1hZGUgY2hhbmdlcyB0byB0aGUgY3VycmVudCBwb3N0IHdo
+aWNoIHlvdSBoYXZlIG5vdCBzYXZlZC4gQ29udGludWUgd2l0aG91dCBzYXZpbmc/JywKCQkJ
+J2Rlc2NyaXB0aW9uX2ZvcicgICAgID0+ICdEZXNjcmlwdGlvbiBmb3InLAoJCQknZmFpbGVk
+JyAgICAgICAgICAgICAgPT4gJ0luc2VydCBmYWlsZWQuJywKCQkJJ2ZpbGVfc2VsZWN0b3In
+ICAgICAgID0+ICdGaWxlIFNlbGVjdG9yJywKCQkJJ2ZvcmdvdF9maWVsZCcgICAgICAgID0+
+ICdZb3UgZm9yZ290IHRvIGRlZmluZSB0aGUgY3VzdG9tIGZpZWxkIGZvciB1cG1fZmlsZS91
+cG1fZmlsZV9wb3BwZXIgdG8gdXNlLiBFbnN1cmUgdGhhdCB5b3UgaGF2ZSBhIGN1c3RvbSBm
+aWVsZCBhdmFpbGFibGUsIGFuZCB0aGF0IHlvdSBoYXZlIHVwbV9maWxlIGluc3RhbGxlZCBh
+bmQgYWN0aXZhdGVkLCB0aGVuIHZpc2l0IEV4dGVuc2lvbnMgPiB1cG1fZmlsZS4nLAoJCQkn
+bm9fZGVzY3JpcHRpb24nICAgICAgPT4gJ05vIGRlc2NyaXB0aW9uIGhhcyBiZWVuIGRlZmlu
+ZWQgZm9yIHRoaXMgZmlsZS4nLAoJCQkncGFja2V0X2N1c3RvbV9maWVsZCcgPT4gJ1BhY2tl
+dCBDdXN0b20gRmllbGQnLAoJCQkncmV0dXJuJyAgICAgICAgICAgICAgPT4gJ1JldHVybiB0
+byBlZGl0aW5nIHRoZSBwb3N0PycsCgkJCSdzdWNjZXNzJyAgICAgICAgICAgICA9PiAnU3Vj
+Y2Vzcy4nLAoJCQkndmlld19hbGwnICAgICAgICAgICAgPT4gJ1ZpZXcgQWxsJwoJCSk7CgoJ
+CXJldHVybiBzdHJ0cigkbGFuZ1skdmFyXSwgJGF0dHMpOwoJfSI7czo0OiJoZWxwIjtzOjI3
+MToiaDEuIHVwbV9maWxlX3BvcHBlcgoKVGhpcyBwbHVnaW4gYWRkcyBhIGxpbmsgdG8gYSBw
+b3B1cCB3aW5kb3cgb2YgYSBsaXN0IG9mIHlvdXIgZmlsZXMsIHRvIGJlIHVzZWQgd2l0aCB1
+cG1fZmlsZS4gdXBtX2ZpbGUgaXMgcmVxdWlyZWQgaW4gb3JkZXIgZm9yIHVwbV9maWxlX3Bv
+cHBlciB0byB3b3JrLgoKVGhlICJBdHRhY2giIGljb24gaXMgZnJvbSAiTWFyayBKYW1lcycg
+U2lsa+KAnWljb24gc2V0IjpodHRwOi8vd3d3LmZhbWZhbWZhbS5jb20vbGFiL2ljb25zL3Np
+bGsvLiI7czo4OiJoZWxwX3JhdyI7czoyNzE6ImgxLiB1cG1fZmlsZV9wb3BwZXIKClRoaXMg
+cGx1Z2luIGFkZHMgYSBsaW5rIHRvIGEgcG9wdXAgd2luZG93IG9mIGEgbGlzdCBvZiB5b3Vy
+IGZpbGVzLCB0byBiZSB1c2VkIHdpdGggdXBtX2ZpbGUuIHVwbV9maWxlIGlzIHJlcXVpcmVk
+IGluIG9yZGVyIGZvciB1cG1fZmlsZV9wb3BwZXIgdG8gd29yay4KClRoZSAiQXR0YWNoIiBp
+Y29uIGlzIGZyb20gIk1hcmsgSmFtZXMnIFNpbGvigJ1pY29uIHNldCI6aHR0cDovL3d3dy5m
+YW1mYW1mYW0uY29tL2xhYi9pY29ucy9zaWxrLy4iO3M6MTU6ImFsbG93X2h0bWxfaGVscCI7
+aTowO3M6MzoibWQ1IjtzOjMyOiIwYTY4ZjU1MTM3ODVmOGYwMjA4OTVlNGQ1Mjg2MTI2ZSI7
+fQ==