diff --git a/README.textile b/README.textile new file mode 100644 index 0000000..bcb2e55 --- /dev/null +++ b/README.textile @@ -0,0 +1,71 @@ +h1. jcr_image_custom + +Adds a single extra custom field of up to 255 characters to the "Content › Images":http://docs.textpattern.io/administration/images-panel panel and provides a corresponding tag to output the custom field. + + +h2. Use cases + +Use whenever extra information needs to be stored with an image. For example: + +* Store a youtube/vimeo link or video-ID with an image for generating custom video poster images. +* Store the download url of a corresponding hi-res press image not stored in txp. +* … + + +h2(#installation). Installation + +Paste the code into the _Admin › Plugins_ panel, install and enable the plugin. + + +h2(#tags). Tags + +bc. + +Outputs the content of the image custom field. + +h3. Tag attributes + +*escape* +Escape HTML entities such as @<@, @>@ and @&@ prior to echoing the field contents. +Example: Use @escape=""@ to suppress conversion. Default: @html@. + + +h2(#examples). Example + +Produce a gallery of custom video poster-images (from images assigned to the image category "videos") that open a corresponding youtube video (defined in the image custom field) in a lightbox modal: + +bc. + " data-lity> + + + + +p. where the image custom field is used to store the Video ID of the YouTube video. This example uses the "lity":http://sorgalla.com/lity/ lightbox script. + + +h2. Changing the label of the custom field + +The name of custom field can be changed by specifying a new label using the _Install from Textpack_ field in the "Admin › Languages":http://docs.textpattern.io/administration/languages-panel panel. Enter your own information in the following pattern and click *Upload*: + +bc.. #@admin +#@language en-gb +jcr_image_custom => Your label + +p. replacing @en-gb@ with your own language and @Your label@ with your own desired label. + + +h2(#deinstallation). De-installation + +The plugin cleans up after itself: deinstalling the plugin removes the extra column from the database. To stop using the plugin but keep the database tables, just disable (deactivate) the plugin but don't delete it. + + +h2(#changelog). Changelog + +h3. Version 0.1 – 2016/04/16 + +* First release + + +h2(#credits). Credits + +Robert Wetzlmayr’s "wet_profile":https://github.com/rwetzlmayr/wet_profile plugin for the starting point, and further examples by "Stef Dawson":http://www.stefdawson.com and "Jukka Svahn":https://github.com/gocom. \ No newline at end of file diff --git a/jcr_image_custom.php b/jcr_image_custom.php new file mode 100644 index 0000000..052381a --- /dev/null +++ b/jcr_image_custom.php @@ -0,0 +1,268 @@ + abc_myplugin-0.1.txt + +// Plugin name is optional. If unset, it will be extracted from the current +// file name. Plugin names should start with a three letter prefix which is +// unique and reserved for each plugin author ("abc" is just an example). +// Uncomment and edit this line to override: +$plugin['name'] = 'jcr_image_custom'; + +// Allow raw HTML help, as opposed to Textile. +// 0 = Plugin help is in Textile format, no raw HTML allowed (default). +// 1 = Plugin help is in raw HTML. Not recommended. +# $plugin['allow_html_help'] = 1; + +$plugin['version'] = '0.1'; +$plugin['author'] = 'jcr / txpbuilders'; +$plugin['author_uri'] = 'http://txp.builders'; +$plugin['description'] = 'Adds a custom field to the images panel'; + +// Plugin load order: +// The default value of 5 would fit most plugins, while for instance comment +// spam evaluators or URL redirectors would probably want to run earlier +// (1...4) to prepare the environment for everything else that follows. +// Values 6...9 should be considered for plugins which would work late. +// This order is user-overrideable. +$plugin['order'] = '5'; + +// Plugin 'type' defines where the plugin is loaded +// 0 = public : only on the public side of the website (default) +// 1 = public+admin : on both the public and admin side +// 2 = library : only when include_plugin() or require_plugin() is called +// 3 = admin : only on the admin side (no AJAX) +// 4 = admin+ajax : only on the admin side (AJAX supported) +// 5 = public+admin+ajax : on both the public and admin side (AJAX supported) +$plugin['type'] = '1'; + +// Plugin "flags" signal the presence of optional capabilities to the core plugin loader. +// Use an appropriately OR-ed combination of these flags. +// The four high-order bits 0xf000 are available for this plugin's private use +if (!defined('PLUGIN_HAS_PREFS')) define('PLUGIN_HAS_PREFS', 0x0001); // This plugin wants to receive "plugin_prefs.{$plugin['name']}" events +if (!defined('PLUGIN_LIFECYCLE_NOTIFY')) define('PLUGIN_LIFECYCLE_NOTIFY', 0x0002); // This plugin wants to receive "plugin_lifecycle.{$plugin['name']}" events + +$plugin['flags'] = ''; + +// Plugin 'textpack' is optional. It provides i18n strings to be used in conjunction with gTxt(). +// Syntax: +// ## arbitrary comment +// #@event +// #@language ISO-LANGUAGE-CODE +// abc_string_name => Localized String + +$plugin['textpack'] = <<< EOT +#@admin +#@language en-gb +jcr_image_custom => Video ID +#@language de-de +jcr_image_custom => Video ID +EOT; +// End of textpack + +if (!defined('txpinterface')) + @include_once('zem_tpl.php'); + +# --- BEGIN PLUGIN CODE --- +class jcr_image_custom +{ + /** + * Initialise. + */ + function __construct() + { + register_callback(array(__CLASS__, 'lifecycle'), 'plugin_lifecycle.jcr_image_custom'); + register_callback(array(__CLASS__, 'ui'), 'image_ui', 'extend_detail_form'); + register_callback(array(__CLASS__, 'save'), 'image', 'image_save'); + } + + /** + * Add and remove custom field from txp_image table. + * + * @param $event string + * @param $step string The lifecycle phase of this plugin + */ + public static function lifecycle($event, $step) + { + switch ($step) { + case 'enabled': + break; + case 'disabled': + break; + case 'installed': + safe_alter( + 'txp_image', + 'ADD COLUMN jcr_image_custom VARCHAR(255) NULL AFTER thumb_h' + ); + break; + case 'deleted': + safe_alter( + 'txp_image', + 'DROP COLUMN jcr_image_custom' + ); + break; + } + return; + } + + /** + * Paint additional fields for image custom field + * + * @param $event string + * @param $step string + * @param $dummy string + * @param $rs array The current image's data + * @return string + */ + public static function ui($event, $step, $dummy, $rs) + { + extract(lAtts(array( + 'jcr_image_custom' => '' + ), $rs, 0)); + + return + inputLabel('jcr_image_custom', fInput('text', 'jcr_image_custom', $jcr_image_custom, '', '', '', INPUT_REGULAR, '', 'jcr_image_custom'), 'jcr_image_custom').n; + } + + /** + * Save additional image custom fields + * + * @param $event string + * @param $step string + */ + public static function save($event, $step) + { + extract(doSlash(psa(array('jcr_image_custom', 'id')))); + $id = assert_int($id); + safe_update('txp_image', + "jcr_image_custom = '$jcr_image_custom'", + "id = $id" + ); + } +} + +if (txpinterface === 'admin') { + + new jcr_image_custom; + +} elseif (txpinterface === 'public') { + + if (class_exists('\Textpattern\Tag\Registry')) { + Txp::get('\Textpattern\Tag\Registry') + ->register('jcr_image_custom'); + } + +} + + /** + * Public tag: Output custom image field + * @param string $atts[escape] Convert special characters to HTML entities. + * @return string custom field output + * + * + * + */ + + function jcr_image_custom($atts) + { + global $thisimage; + + assert_image(); + + extract(lAtts(array( + 'escape' => 'html', + ), $atts)); + + return ($escape == 'html') + ? txpspecialchars($thisimage['jcr_image_custom']) + : $thisimage['jcr_image_custom']; + } +# --- END PLUGIN CODE --- +if (0) { +?> + + + diff --git a/jcr_image_custom_v0.1.txt b/jcr_image_custom_v0.1.txt new file mode 100644 index 0000000..61fb36d --- /dev/null +++ b/jcr_image_custom_v0.1.txt @@ -0,0 +1,134 @@ +# Name: jcr_image_custom v0.1 +# Type: Admin/Public plugin +# Adds a custom field to the images panel +# Author: jcr / txpbuilders +# URL: http://txp.builders +# Recommended load order: 5 + +# ..................................................................... +# This is a plugin for Textpattern CMS - http://textpattern.com/ +# To install: textpattern > admin > plugins +# Paste the following text into the 'Install plugin' box: +# ..................................................................... + +YToxNTp7czo0OiJuYW1lIjtzOjE2OiJqY3JfaW1hZ2VfY3VzdG9tIjtzOjc6InZlcnNpb24i +O3M6MzoiMC4xIjtzOjg6InJldmlzaW9uIjtzOjA6IiI7czo2OiJhdXRob3IiO3M6MTc6Impj +ciAvIHR4cGJ1aWxkZXJzIjtzOjEwOiJhdXRob3JfdXJpIjtzOjE5OiJodHRwOi8vdHhwLmJ1 +aWxkZXJzIjtzOjExOiJkZXNjcmlwdGlvbiI7czozOToiQWRkcyBhIGN1c3RvbSBmaWVsZCB0 +byB0aGUgaW1hZ2VzIHBhbmVsIjtzOjU6Im9yZGVyIjtzOjE6IjUiO3M6NDoidHlwZSI7czox +OiIxIjtzOjU6ImZsYWdzIjtzOjA6IiI7czo4OiJ0ZXh0cGFjayI7czoxMDA6IiNAYWRtaW4K +I0BsYW5ndWFnZSBlbi1nYgpqY3JfaW1hZ2VfY3VzdG9tID0+IFZpZGVvIElECiNAbGFuZ3Vh +Z2UgZGUtZGUKamNyX2ltYWdlX2N1c3RvbSA9PiBWaWRlbyBJRAoiO3M6MTA6ImxvYWRfb3Jk +ZXIiO3M6MToiNSI7czo0OiJoZWxwIjtzOjMyMjM6IjxoMT5qY3JfaW1hZ2VfY3VzdG9tPC9o +MT4KCjxwPkFkZHMgYSBzaW5nbGUgZXh0cmEgY3VzdG9tIGZpZWxkIG9mIHVwIHRvIDI1NSBj +aGFyYWN0ZXJzIHRvIHRoZSA8YSBocmVmPSJodHRwOi8vZG9jcy50ZXh0cGF0dGVybi5pby9h +ZG1pbmlzdHJhdGlvbi9pbWFnZXMtcGFuZWwiPkNvbnRlbnQg4oC6IEltYWdlczwvYT4gcGFu +ZWwgYW5kIHByb3ZpZGVzIGEgY29ycmVzcG9uZGluZyB0YWcgdG8gb3V0cHV0IHRoZSBjdXN0 +b20gZmllbGQuPC9wPgoKCjxoMj5Vc2UgY2FzZXM8L2gyPgoKPHA+VXNlIHdoZW5ldmVyIGV4 +dHJhIGluZm9ybWF0aW9uIG5lZWRzIHRvIGJlIHN0b3JlZCB3aXRoIGFuIGltYWdlLiBGb3Ig +ZXhhbXBsZTo8L3A+Cgo8dWw+Cgk8bGk+U3RvcmUgYSB5b3V0dWJlL3ZpbWVvIGxpbmsgb3Ig +dmlkZW8tSUQgd2l0aCBhbiBpbWFnZSBmb3IgZ2VuZXJhdGluZyBjdXN0b20gdmlkZW8gcG9z +dGVyIGltYWdlcy48L2xpPgoJPGxpPlN0b3JlIHRoZSBkb3dubG9hZCB1cmwgb2YgYSBjb3Jy +ZXNwb25kaW5nIGhpLXJlcyBwcmVzcyBpbWFnZSBub3Qgc3RvcmVkIGluIHR4cC48L2xpPgoJ +PGxpPuKApjwvbGk+CjwvdWw+CgoKPGgyIGlkPSJpbnN0YWxsYXRpb24iPkluc3RhbGxhdGlv +bjwvaDI+Cgo8cD5QYXN0ZSB0aGUgY29kZSBpbnRvIHRoZSAgPGVtPkFkbWluIOKAuiBQbHVn +aW5zPC9lbT4gcGFuZWwsIGluc3RhbGwgYW5kIGVuYWJsZSB0aGUgcGx1Z2luLjwvcD4KCgo8 +aDIgaWQ9InRhZ3MiPlRhZ3M8L2gyPgoKPHByZT48Y29kZT4mbHQ7dHhwOmpjcl9pbWFnZV9j +dXN0b20gLyZndDs8L2NvZGU+PC9wcmU+Cgo8cD5PdXRwdXRzIHRoZSBjb250ZW50IG9mIHRo +ZSBpbWFnZSBjdXN0b20gZmllbGQuPC9wPgoKPGgzPlRhZyBhdHRyaWJ1dGVzPC9oMz4KCjxw +PjxzdHJvbmc+ZXNjYXBlPC9zdHJvbmc+PGJyIC8+CkVzY2FwZSA8c3BhbiBjbGFzcz0iY2Fw +cyI+SFRNTDwvc3Bhbj4gZW50aXRpZXMgc3VjaCBhcyA8Y29kZT4mbHQ7PC9jb2RlPiwgPGNv +ZGU+Jmd0OzwvY29kZT4gYW5kIDxjb2RlPiZhbXA7PC9jb2RlPiBwcmlvciB0byBlY2hvaW5n +IHRoZSBmaWVsZCBjb250ZW50cy48YnIgLz4KRXhhbXBsZTogVXNlIDxjb2RlPmVzY2FwZT0m +cXVvdDsmcXVvdDs8L2NvZGU+IHRvIHN1cHByZXNzIGNvbnZlcnNpb24uIERlZmF1bHQ6IDxj +b2RlPmh0bWw8L2NvZGU+LjwvcD4KCgo8aDIgaWQ9ImV4YW1wbGVzIj5FeGFtcGxlPC9oMj4K +CjxwPlByb2R1Y2UgYSBnYWxsZXJ5IG9mIGN1c3RvbSB2aWRlbyBwb3N0ZXItaW1hZ2VzIChm +cm9tIGltYWdlcyBhc3NpZ25lZCB0byB0aGUgaW1hZ2UgY2F0ZWdvcnkgJiM4MjIwO3ZpZGVv +cyYjODIyMTspIHRoYXQgb3BlbiBhIGNvcnJlc3BvbmRpbmcgeW91dHViZSB2aWRlbyAoZGVm +aW5lZCBpbiB0aGUgaW1hZ2UgY3VzdG9tIGZpZWxkKSBpbiBhIGxpZ2h0Ym94IG1vZGFsOjwv +cD4KCjxwcmU+PGNvZGU+Jmx0O3R4cDppbWFnZXMgd3JhcHRhZz0mcXVvdDt1bCZxdW90OyBi +cmVhaz0mcXVvdDtsaSZxdW90OyBjYXRlZ29yeT0mcXVvdDt2aWRlb3MmcXVvdDsgY2xhc3M9 +JnF1b3Q7dmlkZW8tZ2FsbGVyeSZxdW90OyZndDsKICAmbHQ7YSBocmVmPSZxdW90Oy8vd3d3 +LnlvdXR1YmUuY29tL3dhdGNoP3Y9Jmx0O3R4cDpqY3JfaW1hZ2VfY3VzdG9tIC8mZ3Q7JnF1 +b3Q7IHRpdGxlPSZxdW90OyZsdDt0eHA6aW1hZ2VfaW5mbyB0eXBlPSZxdW90O2NhcHRpb24m +cXVvdDsgLyZndDsmcXVvdDsgZGF0YS1saXR5Jmd0OwogICAgJmx0O3R4cDp0aHVtYm5haWwg +LyZndDsKICAmbHQ7L2EmZ3Q7CiZsdDsvdHhwOmltYWdlcyZndDs8L2NvZGU+PC9wcmU+Cgo8 +cD53aGVyZSB0aGUgaW1hZ2UgY3VzdG9tIGZpZWxkIGlzIHVzZWQgdG8gc3RvcmUgdGhlIFZp +ZGVvIElEIG9mIHRoZSBZb3VUdWJlIHZpZGVvLiBUaGlzIGV4YW1wbGUgdXNlcyB0aGUgPGEg +aHJlZj0iaHR0cDovL3NvcmdhbGxhLmNvbS9saXR5LyI+bGl0eTwvYT4gbGlnaHRib3ggc2Ny +aXB0LjwvcD4KCgo8aDI+Q2hhbmdpbmcgdGhlIGxhYmVsIG9mIHRoZSBjdXN0b20gZmllbGQ8 +L2gyPgoKPHA+VGhlIG5hbWUgb2YgY3VzdG9tIGZpZWxkIGNhbiBiZSBjaGFuZ2VkIGJ5IHNw +ZWNpZnlpbmcgYSBuZXcgbGFiZWwgdXNpbmcgdGhlIDxlbT5JbnN0YWxsIGZyb20gVGV4dHBh +Y2s8L2VtPiBmaWVsZCBpbiB0aGUgPGEgaHJlZj0iaHR0cDovL2RvY3MudGV4dHBhdHRlcm4u +aW8vYWRtaW5pc3RyYXRpb24vbGFuZ3VhZ2VzLXBhbmVsLmh0bWwiPkFkbWluIOKAuiBMYW5n +dWFnZXM8L2E+IHBhbmVsLiBFbnRlciB5b3VyIG93biBpbmZvcm1hdGlvbiBpbiB0aGUgZm9s +bG93aW5nIHBhdHRlcm4gYW5kIGNsaWNrIDxzdHJvbmc+VXBsb2FkPC9zdHJvbmc+OjwvcD4K +CjxwcmU+PGNvZGU+I0BhZG1pbgojQGxhbmd1YWdlIGVuLWdiCmpjcl9pbWFnZV9jdXN0b20g +PSZndDsgWW91ciBsYWJlbDwvY29kZT48L3ByZT4KCjxwPnJlcGxhY2luZyA8Y29kZT5lbi1n +YjwvY29kZT4gd2l0aCB5b3VyIG93biBsYW5ndWFnZSBhbmQgPGNvZGU+WW91ciBsYWJlbDwv +Y29kZT4gd2l0aCB5b3VyIG93biBkZXNpcmVkIGxhYmVsLjwvcD4KCgo8aDIgaWQ9ImRlaW5z +dGFsbGF0aW9uIj5EZS1pbnN0YWxsYXRpb248L2gyPgoKPHA+VGhlIHBsdWdpbiBjbGVhbnMg +dXAgYWZ0ZXIgaXRzZWxmOiBkZWluc3RhbGxpbmcgdGhlIHBsdWdpbiByZW1vdmVzIHRoZSBl +eHRyYSBjb2x1bW4gZnJvbSB0aGUgZGF0YWJhc2UuIFRvIHN0b3AgdXNpbmcgdGhlIHBsdWdp +biBidXQga2VlcCB0aGUgZGF0YWJhc2UgdGFibGVzLCBqdXN0IGRpc2FibGUgKGRlYWN0aXZh +dGUpIHRoZSBwbHVnaW4gYnV0IGRvbiYjODIxNzt0IGRlbGV0ZSBpdC48L3A+CgoKPGgyIGlk +PSJjaGFuZ2Vsb2ciPkNoYW5nZWxvZzwvaDI+Cgo8aDM+VmVyc2lvbiAwLjEg4oCTIDIwMTYv +MDQvMTY8L2gzPgoKPHVsPgoJPGxpPkZpcnN0IHJlbGVhc2U8L2xpPgo8L3VsPgoKCjxoMiBp +ZD0iY3JlZGl0cyI+Q3JlZGl0czwvaDI+Cgo8cD5Sb2JlcnQgV2V0emxtYXly4oCZcyA8YSBo +cmVmPSJodHRwczovL2dpdGh1Yi5jb20vcndldHpsbWF5ci93ZXRfcHJvZmlsZSI+d2V0X3By +b2ZpbGU8L2E+IHBsdWdpbiBmb3IgdGhlIHN0YXJ0aW5nIHBvaW50LCBhbmQgZnVydGhlciBl +eGFtcGxlcyBieSA8YSBocmVmPSJodHRwOi8vd3d3LnN0ZWZkYXdzb24uY29tIj5TdGVmIERh +d3NvbjwvYT4gYW5kIDxhIGhyZWY9Imh0dHBzOi8vZ2l0aHViLmNvbS9nb2NvbSI+SnVra2Eg +U3ZhaG48L2E+LjwvcD4iO3M6MzoiY3NzIjtzOjA6IiI7czo0OiJjb2RlIjtzOjI3MTE6ImNs +YXNzIGpjcl9pbWFnZV9jdXN0b20KewoJLyoqCgkgKiBJbml0aWFsaXNlLgoJICovCgkgZnVu +Y3Rpb24gX19jb25zdHJ1Y3QoKQoJewoJCXJlZ2lzdGVyX2NhbGxiYWNrKGFycmF5KF9fQ0xB +U1NfXywgJ2xpZmVjeWNsZScpLCAncGx1Z2luX2xpZmVjeWNsZS5qY3JfaW1hZ2VfY3VzdG9t +Jyk7CgkJcmVnaXN0ZXJfY2FsbGJhY2soYXJyYXkoX19DTEFTU19fLCAndWknKSwgJ2ltYWdl +X3VpJywgJ2V4dGVuZF9kZXRhaWxfZm9ybScpOwoJCXJlZ2lzdGVyX2NhbGxiYWNrKGFycmF5 +KF9fQ0xBU1NfXywgJ3NhdmUnKSwgJ2ltYWdlJywgJ2ltYWdlX3NhdmUnKTsKCX0KCiAgLyoq +CiAgICogQWRkIGFuZCByZW1vdmUgY3VzdG9tIGZpZWxkIGZyb20gdHhwX2ltYWdlIHRhYmxl +LgogICAqCiAgICogQHBhcmFtICRldmVudCBzdHJpbmcKICAgKiBAcGFyYW0gJHN0ZXAgc3Ry +aW5nICBUaGUgbGlmZWN5Y2xlIHBoYXNlIG9mIHRoaXMgcGx1Z2luCiAgICovCiAgcHVibGlj +IHN0YXRpYyBmdW5jdGlvbiBsaWZlY3ljbGUoJGV2ZW50LCAkc3RlcCkKICB7CiAgICAgIHN3 +aXRjaCAoJHN0ZXApIHsKICAgICAgICAgIGNhc2UgJ2VuYWJsZWQnOgogICAgICAgICAgICAg +IGJyZWFrOwogICAgICAgICAgY2FzZSAnZGlzYWJsZWQnOgogICAgICAgICAgICAgIGJyZWFr +OwogICAgICAgICAgY2FzZSAnaW5zdGFsbGVkJzoKICAgICAgICAgICAgICBzYWZlX2FsdGVy +KAogICAgICAgICAgICAgICAgJ3R4cF9pbWFnZScsCiAgICAgICAgICAgICAgICAnQUREIENP +TFVNTiBqY3JfaW1hZ2VfY3VzdG9tIFZBUkNIQVIoMjU1KSBOVUxMIEFGVEVSIHRodW1iX2gn +CiAgICAgICAgICAgICAgKTsKICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgIGNhc2Ug +J2RlbGV0ZWQnOgogICAgICAgICAgICAgIHNhZmVfYWx0ZXIoCiAgICAgICAgICAgICAgICAn +dHhwX2ltYWdlJywKICAgICAgICAgICAgICAgICdEUk9QIENPTFVNTiBqY3JfaW1hZ2VfY3Vz +dG9tJwogICAgICAgICAgICAgICk7CiAgICAgICAgICAgICAgYnJlYWs7CiAgICAgIH0KICAg +ICAgcmV0dXJuOwogIH0KCgkvKioKCSAqIFBhaW50IGFkZGl0aW9uYWwgZmllbGRzIGZvciBp +bWFnZSBjdXN0b20gZmllbGQKCSAqCgkgKiBAcGFyYW0gJGV2ZW50IHN0cmluZwoJICogQHBh +cmFtICRzdGVwIHN0cmluZwoJICogQHBhcmFtICRkdW1teSBzdHJpbmcKCSAqIEBwYXJhbSAk +cnMgYXJyYXkgVGhlIGN1cnJlbnQgaW1hZ2UncyBkYXRhCgkgKiBAcmV0dXJuIHN0cmluZwoJ +ICovCglwdWJsaWMgc3RhdGljIGZ1bmN0aW9uIHVpKCRldmVudCwgJHN0ZXAsICRkdW1teSwg +JHJzKQoJewoJCWV4dHJhY3QobEF0dHMoYXJyYXkoCgkJCSdqY3JfaW1hZ2VfY3VzdG9tJyA9 +PiAnJwoJCSksICRycywgMCkpOwoKCQlyZXR1cm4KCQkJaW5wdXRMYWJlbCgnamNyX2ltYWdl +X2N1c3RvbScsIGZJbnB1dCgndGV4dCcsICdqY3JfaW1hZ2VfY3VzdG9tJywgJGpjcl9pbWFn +ZV9jdXN0b20sICcnLCAnJywgJycsIElOUFVUX1JFR1VMQVIsICcnLCAnamNyX2ltYWdlX2N1 +c3RvbScpLCAnamNyX2ltYWdlX2N1c3RvbScpLm47Cgl9CgoJLyoqCgkgKiBTYXZlIGFkZGl0 +aW9uYWwgaW1hZ2UgY3VzdG9tIGZpZWxkcwoJICoKCSAqIEBwYXJhbSAkZXZlbnQgc3RyaW5n +CgkgKiBAcGFyYW0gJHN0ZXAgc3RyaW5nCgkgKi8KCXB1YmxpYyBzdGF0aWMgZnVuY3Rpb24g +c2F2ZSgkZXZlbnQsICRzdGVwKQoJewoJCWV4dHJhY3QoZG9TbGFzaChwc2EoYXJyYXkoJ2pj +cl9pbWFnZV9jdXN0b20nLCAnaWQnKSkpKTsKCQkkaWQgPSBhc3NlcnRfaW50KCRpZCk7CgkJ +c2FmZV91cGRhdGUoJ3R4cF9pbWFnZScsCgkJICAiamNyX2ltYWdlX2N1c3RvbSA9ICckamNy +X2ltYWdlX2N1c3RvbSciLAoJCQkiaWQgPSAkaWQiCgkJKTsKCX0KfQoKaWYgKHR4cGludGVy +ZmFjZSA9PT0gJ2FkbWluJykgewoKICAgIG5ldyBqY3JfaW1hZ2VfY3VzdG9tOwoKfSBlbHNl +aWYgKHR4cGludGVyZmFjZSA9PT0gJ3B1YmxpYycpIHsKCiAgICBpZiAoY2xhc3NfZXhpc3Rz +KCdcVGV4dHBhdHRlcm5cVGFnXFJlZ2lzdHJ5JykpIHsKICAgICAgICBUeHA6OmdldCgnXFRl +eHRwYXR0ZXJuXFRhZ1xSZWdpc3RyeScpCiAgICAgICAgICAgIC0+cmVnaXN0ZXIoJ2pjcl9p +bWFnZV9jdXN0b20nKTsKICAgIH0KCn0KCiAgLyoqCiAgICogUHVibGljIHRhZzogT3V0cHV0 +IGN1c3RvbSBpbWFnZSBmaWVsZAogICAqIEBwYXJhbSAgc3RyaW5nICRhdHRzW2VzY2FwZV0g +Q29udmVydCBzcGVjaWFsIGNoYXJhY3RlcnMgdG8gSFRNTCBlbnRpdGllcy4KICAgKiBAcmV0 +dXJuIHN0cmluZyAgY3VzdG9tIGZpZWxkIG91dHB1dAogICAqIDxjb2RlPgogICAqICAgICAg +ICA8dHhwOmpjcl9pbWFnZV9jdXN0b20gZXNjYXBlPSJodG1sIiAvPgogICAqIDwvY29kZT4K +ICAgKi8KCiAgICBmdW5jdGlvbiBqY3JfaW1hZ2VfY3VzdG9tKCRhdHRzKQogICAgewogICAg +ICAgIGdsb2JhbCAkdGhpc2ltYWdlOwoKICAgICAgICBhc3NlcnRfaW1hZ2UoKTsKCiAgICAg +ICAgZXh0cmFjdChsQXR0cyhhcnJheSgKICAgICAgICAgICAgJ2VzY2FwZScgPT4gJ2h0bWwn +LAogICAgICAgICksICRhdHRzKSk7CgogICAgICAgIHJldHVybiAoJGVzY2FwZSA9PSAnaHRt +bCcpCiAgICAgICAgICAgID8gdHhwc3BlY2lhbGNoYXJzKCR0aGlzaW1hZ2VbJ2pjcl9pbWFn +ZV9jdXN0b20nXSkKICAgICAgICAgICAgOiAkdGhpc2ltYWdlWydqY3JfaW1hZ2VfY3VzdG9t +J107CiAgICB9IjtzOjM6Im1kNSI7czozMjoiZDc2NTQ5ODMzODkwYjUxODVlMzZmNDdlOTlh +YTlhMTgiO30=