From ee6d543eede868f16d69c6529b7366d55630c9ff Mon Sep 17 00:00:00 2001 From: Tim Steiner <tsteiner2@unl.edu> Date: Mon, 21 Feb 2011 18:53:18 +0000 Subject: [PATCH] [gh-94] Merging from testing into staging git-svn-id: file:///tmp/wdn_thm_drupal/branches/drupal-7.x/staging@532 20a16fea-79d4-4915-8869-1ea9d5ebf173 --- sites/all/modules/imce_rename/LICENSE.txt | 274 ++++++++++++++++++ sites/all/modules/imce_rename/imce_rename.css | 8 + .../all/modules/imce_rename/imce_rename.info | 16 + .../modules/imce_rename/imce_rename.install | 35 +++ sites/all/modules/imce_rename/imce_rename.js | 43 +++ .../modules/imce_rename/imce_rename.module | 147 ++++++++++ sites/all/modules/imce_rename/rename.png | Bin 0 -> 397 bytes 7 files changed, 523 insertions(+) create mode 100644 sites/all/modules/imce_rename/LICENSE.txt create mode 100644 sites/all/modules/imce_rename/imce_rename.css create mode 100644 sites/all/modules/imce_rename/imce_rename.info create mode 100644 sites/all/modules/imce_rename/imce_rename.install create mode 100644 sites/all/modules/imce_rename/imce_rename.js create mode 100644 sites/all/modules/imce_rename/imce_rename.module create mode 100644 sites/all/modules/imce_rename/rename.png diff --git a/sites/all/modules/imce_rename/LICENSE.txt b/sites/all/modules/imce_rename/LICENSE.txt new file mode 100644 index 00000000..2c095c8d --- /dev/null +++ b/sites/all/modules/imce_rename/LICENSE.txt @@ -0,0 +1,274 @@ +GNU GENERAL PUBLIC LICENSE + + Version 2, June 1991 + +Copyright (C) 1989, 1991 Free Software Foundation, Inc. 675 Mass Ave, +Cambridge, MA 02139, USA. Everyone is permitted to copy and distribute +verbatim copies of this license document, but changing it is not allowed. + + Preamble + +The licenses for most software are designed to take away your freedom to +share and change it. By contrast, the GNU General Public License is +intended to guarantee your freedom to share and change free software--to +make sure the software is free for all its users. This General Public License +applies to most of the Free Software Foundation's software and to any other +program whose authors commit to using it. (Some other Free Software +Foundation software is covered by the GNU Library General Public License +instead.) You can apply it to your programs, too. + +When we speak of free software, we are referring to freedom, not price. Our +General Public Licenses are designed to make sure that you have the +freedom to distribute copies of free software (and charge for this service if +you wish), that you receive source code or can get it if you want it, that you +can change the software or use pieces of it in new free programs; and that +you know you can do these things. + +To protect your rights, we need to make restrictions that forbid anyone to +deny you these rights or to ask you to surrender the rights. These restrictions +translate to certain responsibilities for you if you distribute copies of the +software, or if you modify it. + +For example, if you distribute copies of such a program, whether gratis or for +a fee, you must give the recipients all the rights that you have. You must make +sure that they, too, receive or can get the source code. And you must show +them these terms so they know their rights. + +We protect your rights with two steps: (1) copyright the software, and (2) +offer you this license which gives you legal permission to copy, distribute +and/or modify the software. + +Also, for each author's protection and ours, we want to make certain that +everyone understands that there is no warranty for this free software. If the +software is modified by someone else and passed on, we want its recipients +to know that what they have is not the original, so that any problems +introduced by others will not reflect on the original authors' reputations. + +Finally, any free program is threatened constantly by software patents. We +wish to avoid the danger that redistributors of a free program will individually +obtain patent licenses, in effect making the program proprietary. To prevent +this, we have made it clear that any patent must be licensed for everyone's +free use or not licensed at all. + +The precise terms and conditions for copying, distribution and modification +follow. + + GNU GENERAL PUBLIC LICENSE + TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND + MODIFICATION + +0. This License applies to any program or other work which contains a notice +placed by the copyright holder saying it may be distributed under the terms +of this General Public License. The "Program", below, refers to any such +program or work, and a "work based on the Program" means either the +Program or any derivative work under copyright law: that is to say, a work +containing the Program or a portion of it, either verbatim or with +modifications and/or translated into another language. (Hereinafter, translation +is included without limitation in the term "modification".) Each licensee is +addressed as "you". + +Activities other than copying, distribution and modification are not covered +by this License; they are outside its scope. The act of running the Program is +not restricted, and the output from the Program is covered only if its contents +constitute a work based on the Program (independent of having been made +by running the Program). Whether that is true depends on what the Program +does. + +1. You may copy and distribute verbatim copies of the Program's source +code as you receive it, in any medium, provided that you conspicuously and +appropriately publish on each copy an appropriate copyright notice and +disclaimer of warranty; keep intact all the notices that refer to this License +and to the absence of any warranty; and give any other recipients of the +Program a copy of this License along with the Program. + +You may charge a fee for the physical act of transferring a copy, and you +may at your option offer warranty protection in exchange for a fee. + +2. You may modify your copy or copies of the Program or any portion of it, +thus forming a work based on the Program, and copy and distribute such +modifications or work under the terms of Section 1 above, provided that you +also meet all of these conditions: + +a) You must cause the modified files to carry prominent notices stating that +you changed the files and the date of any change. + +b) You must cause any work that you distribute or publish, that in whole or in +part contains or is derived from the Program or any part thereof, to be +licensed as a whole at no charge to all third parties under the terms of this +License. + +c) If the modified program normally reads commands interactively when run, +you must cause it, when started running for such interactive use in the most +ordinary way, to print or display an announcement including an appropriate +copyright notice and a notice that there is no warranty (or else, saying that +you provide a warranty) and that users may redistribute the program under +these conditions, and telling the user how to view a copy of this License. +(Exception: if the Program itself is interactive but does not normally print such +an announcement, your work based on the Program is not required to print +an announcement.) + +These requirements apply to the modified work as a whole. If identifiable +sections of that work are not derived from the Program, and can be +reasonably considered independent and separate works in themselves, then +this License, and its terms, do not apply to those sections when you distribute +them as separate works. But when you distribute the same sections as part +of a whole which is a work based on the Program, the distribution of the +whole must be on the terms of this License, whose permissions for other +licensees extend to the entire whole, and thus to each and every part +regardless of who wrote it. + +Thus, it is not the intent of this section to claim rights or contest your rights to +work written entirely by you; rather, the intent is to exercise the right to +control the distribution of derivative or collective works based on the +Program. + +In addition, mere aggregation of another work not based on the Program +with the Program (or with a work based on the Program) on a volume of a +storage or distribution medium does not bring the other work under the scope +of this License. + +3. You may copy and distribute the Program (or a work based on it, under +Section 2) in object code or executable form under the terms of Sections 1 +and 2 above provided that you also do one of the following: + +a) Accompany it with the complete corresponding machine-readable source +code, which must be distributed under the terms of Sections 1 and 2 above +on a medium customarily used for software interchange; or, + +b) Accompany it with a written offer, valid for at least three years, to give +any third party, for a charge no more than your cost of physically performing +source distribution, a complete machine-readable copy of the corresponding +source code, to be distributed under the terms of Sections 1 and 2 above on +a medium customarily used for software interchange; or, + +c) Accompany it with the information you received as to the offer to distribute +corresponding source code. (This alternative is allowed only for +noncommercial distribution and only if you received the program in object +code or executable form with such an offer, in accord with Subsection b +above.) + +The source code for a work means the preferred form of the work for +making modifications to it. For an executable work, complete source code +means all the source code for all modules it contains, plus any associated +interface definition files, plus the scripts used to control compilation and +installation of the executable. However, as a special exception, the source +code distributed need not include anything that is normally distributed (in +either source or binary form) with the major components (compiler, kernel, +and so on) of the operating system on which the executable runs, unless that +component itself accompanies the executable. + +If distribution of executable or object code is made by offering access to +copy from a designated place, then offering equivalent access to copy the +source code from the same place counts as distribution of the source code, +even though third parties are not compelled to copy the source along with the +object code. + +4. You may not copy, modify, sublicense, or distribute the Program except as +expressly provided under this License. Any attempt otherwise to copy, +modify, sublicense or distribute the Program is void, and will automatically +terminate your rights under this License. However, parties who have received +copies, or rights, from you under this License will not have their licenses +terminated so long as such parties remain in full compliance. + +5. You are not required to accept this License, since you have not signed it. +However, nothing else grants you permission to modify or distribute the +Program or its derivative works. These actions are prohibited by law if you +do not accept this License. Therefore, by modifying or distributing the +Program (or any work based on the Program), you indicate your acceptance +of this License to do so, and all its terms and conditions for copying, +distributing or modifying the Program or works based on it. + +6. Each time you redistribute the Program (or any work based on the +Program), the recipient automatically receives a license from the original +licensor to copy, distribute or modify the Program subject to these terms and +conditions. You may not impose any further restrictions on the recipients' +exercise of the rights granted herein. You are not responsible for enforcing +compliance by third parties to this License. + +7. If, as a consequence of a court judgment or allegation of patent +infringement or for any other reason (not limited to patent issues), conditions +are imposed on you (whether by court order, agreement or otherwise) that +contradict the conditions of this License, they do not excuse you from the +conditions of this License. If you cannot distribute so as to satisfy +simultaneously your obligations under this License and any other pertinent +obligations, then as a consequence you may not distribute the Program at all. +For example, if a patent license would not permit royalty-free redistribution +of the Program by all those who receive copies directly or indirectly through +you, then the only way you could satisfy both it and this License would be to +refrain entirely from distribution of the Program. + +If any portion of this section is held invalid or unenforceable under any +particular circumstance, the balance of the section is intended to apply and +the section as a whole is intended to apply in other circumstances. + +It is not the purpose of this section to induce you to infringe any patents or +other property right claims or to contest validity of any such claims; this +section has the sole purpose of protecting the integrity of the free software +distribution system, which is implemented by public license practices. Many +people have made generous contributions to the wide range of software +distributed through that system in reliance on consistent application of that +system; it is up to the author/donor to decide if he or she is willing to +distribute software through any other system and a licensee cannot impose +that choice. + +This section is intended to make thoroughly clear what is believed to be a +consequence of the rest of this License. + +8. If the distribution and/or use of the Program is restricted in certain +countries either by patents or by copyrighted interfaces, the original copyright +holder who places the Program under this License may add an explicit +geographical distribution limitation excluding those countries, so that +distribution is permitted only in or among countries not thus excluded. In such +case, this License incorporates the limitation as if written in the body of this +License. + +9. The Free Software Foundation may publish revised and/or new versions +of the General Public License from time to time. Such new versions will be +similar in spirit to the present version, but may differ in detail to address new +problems or concerns. + +Each version is given a distinguishing version number. If the Program specifies +a version number of this License which applies to it and "any later version", +you have the option of following the terms and conditions either of that +version or of any later version published by the Free Software Foundation. If +the Program does not specify a version number of this License, you may +choose any version ever published by the Free Software Foundation. + +10. If you wish to incorporate parts of the Program into other free programs +whose distribution conditions are different, write to the author to ask for +permission. For software which is copyrighted by the Free Software +Foundation, write to the Free Software Foundation; we sometimes make +exceptions for this. Our decision will be guided by the two goals of +preserving the free status of all derivatives of our free software and of +promoting the sharing and reuse of software generally. + + NO WARRANTY + +11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, +THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT +PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE +STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR +OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT +WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, +INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND +PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE +PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL +NECESSARY SERVICING, REPAIR OR CORRECTION. + +12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR +AGREED TO IN WRITING WILL ANY COPYRIGHT HOLDER, OR +ANY OTHER PARTY WHO MAY MODIFY AND/OR +REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE +LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, +SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES +ARISING OUT OF THE USE OR INABILITY TO USE THE +PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF DATA +OR DATA BEING RENDERED INACCURATE OR LOSSES +SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE +PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), EVEN +IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF +THE POSSIBILITY OF SUCH DAMAGES. + + END OF TERMS AND CONDITIONS diff --git a/sites/all/modules/imce_rename/imce_rename.css b/sites/all/modules/imce_rename/imce_rename.css new file mode 100644 index 00000000..6aea26e9 --- /dev/null +++ b/sites/all/modules/imce_rename/imce_rename.css @@ -0,0 +1,8 @@ +/* $Id: imce_rename.css,v 1.1 2010/10/19 08:57:42 aaron1234nz Exp $ */ + +#op-item-rename a, #imce-content #edit-rename { + background-image: url(rename.png); + /*For IMCE 1.x*/ + background-repeat: no-repeat; + padding-left: 20px; +} diff --git a/sites/all/modules/imce_rename/imce_rename.info b/sites/all/modules/imce_rename/imce_rename.info new file mode 100644 index 00000000..5175f088 --- /dev/null +++ b/sites/all/modules/imce_rename/imce_rename.info @@ -0,0 +1,16 @@ +; $Id: imce_rename.info,v 1.1.4.1 2011/01/06 08:49:19 aaron1234nz Exp $ +name = "IMCE Rename" +description = "Adds file and directory renaming functionality to IMCE" +core = "7.x" +package = "Media" +dependencies[] = "imce" + +files[] = "imce_rename.install" +files[] = "imce_rename.module" + +; Information added by drupal.org packaging script on 2011-01-06 +version = "7.x-1.2" +core = "7.x" +project = "imce_rename" +datestamp = "1294306320" + diff --git a/sites/all/modules/imce_rename/imce_rename.install b/sites/all/modules/imce_rename/imce_rename.install new file mode 100644 index 00000000..ff1dd518 --- /dev/null +++ b/sites/all/modules/imce_rename/imce_rename.install @@ -0,0 +1,35 @@ +<?php +// $Id: imce_rename.install,v 1.2 2010/10/06 10:24:30 aaron1234nz Exp $ + +/** + * @file + * Install file for imce_rename + */ + +/** + * Implementation of hook_install() + */ +function imce_rename_install() { + $profiles = variable_get('imce_profiles', array()); + //set crop permissions. make profile#1 have access by default. + foreach ($profiles as $i => $profile) { + foreach ($profile['directories'] as $j => $directory) { + $profiles[$i]['directories'][$j]['rename'] = $i == 1 ? 1 : 0; + } + } + variable_set('imce_profiles', $profiles); +} + +/** + * Implementation of hook_uninstall(). + */ +function imce_rename_uninstall() { + $profiles = variable_get('imce_profiles', array()); + //delete crop permissions. + foreach ($profiles as $i => $profile) { + foreach ($profile['directories'] as $j => $directory) { + unset($profiles[$i]['directories'][$j]['rename']); + } + } + variable_set('imce_profiles', $profiles); +} \ No newline at end of file diff --git a/sites/all/modules/imce_rename/imce_rename.js b/sites/all/modules/imce_rename/imce_rename.js new file mode 100644 index 00000000..a22e0d7f --- /dev/null +++ b/sites/all/modules/imce_rename/imce_rename.js @@ -0,0 +1,43 @@ +//implementation of imce.hookOpSubmit +imce.renameOpSubmit = function(dop) { + if (imce.fopValidate('rename')) { + imce.fopLoading('rename', true); + jQuery.ajax(jQuery.extend(imce.fopSettings('rename'), {success: imce.renameResponse})); + } +}; + +//add hook.load +imce.hooks.load.push(function() { + //set click function for rename tab to toggle crop UI + imce.ops['rename'].func = imce.renamePrepare; +}); + +//populate the text box with the current file or dir name +imce.renamePrepare = function(response) { + var i = 0; + for (var fid in imce.selected) { + jQuery('#edit-new-name').val(unescape(imce.selected[fid].id)); + i++; + } + if (i == 0) { + jQuery('#edit-new-name').val(unescape(imce.conf.dir)); + } + if (i > 1) { + imce.setMessage(Drupal.t('Only one file can be renamed at a time.'), 'error'); + setTimeout(function() {jQuery('#op-close-link').click();}, 5); + } + + //hack to make renaming of directories possible + if (imce.selcount == 0) { + imce.selcount = 1; + imce.selected['__IS_DIR__'] = '__IS_DIR__'; + } +}; + +//custom response. keep track of overwritten files. +imce.renameResponse = function(response) { + imce.processResponse(response); + imce.vars.cache = false; + imce.navigate('.'); //should be folder parent and only trigger when a dir is renamed. + jQuery('#op-close-link').click(); //there is probably a better way to close the dialog than this. +}; diff --git a/sites/all/modules/imce_rename/imce_rename.module b/sites/all/modules/imce_rename/imce_rename.module new file mode 100644 index 00000000..025ebf4e --- /dev/null +++ b/sites/all/modules/imce_rename/imce_rename.module @@ -0,0 +1,147 @@ +<?php +// $Id: imce_rename.module,v 1.5.2.1 2011/01/06 08:49:19 aaron1234nz Exp $ + +/** + * Implementation of hook_form_FORMID_alter(). + */ +function imce_rename_form_imce_fileop_form_alter(&$form, &$form_state, $form_id) { + $imce = &$form_state['build_info']['args'][0]['imce']; + if (imce_perm_exists($imce, 'rename')) { + $form['fset_rename'] = array( + '#type' => 'fieldset', + '#title' => t('Rename'), + ) + imce_rename_form($imce); + array_unshift($form['#validate'], 'imce_rename_prevalidate'); // Needed to override some validation when renaming folders + drupal_add_js(drupal_get_path('module', 'imce_rename') .'/imce_rename.js'); + drupal_add_css(drupal_get_path('module', 'imce_rename') .'/imce_rename.css'); + } +} + +/** + * Implementation of hook_form_FORMID_alter(). + */ +function imce_rename_form_imce_profile_form_alter(&$form, &$form_state, $form_id) { + foreach (element_children($form['profile']['directories']) as $key) { + $form['profile']['directories'][$key]['rename'] = array( + '#type' => 'checkbox', + '#title' => t('Rename'), + '#default_value' => isset($form_state['profile']['directories'][$key]['rename']) ? $form_state['profile']['directories'][$key]['rename'] : 0, + ); + } +} + +/** + * Rename form. + */ +function imce_rename_form(&$imce) { + $form['new_name'] = array( + '#type' => 'textfield', + '#title' => t('New name'), + '#size' => 40, + '#prefix' => '<div class="container-inline">', + ); + + $form['rename'] = array( + '#type' => 'submit', + '#value' => t('Rename'), + '#submit' => $imce['perm']['rename'] ? array('imce_rename_submit') : NULL,//permission for submission + '#suffix' => '</div>', + ); + return $form; +} + +/** + * Prevalidate function for altering the behavior of the imce_fileop_form_validate function + * when renaming folders (ie no file selected) + */ +function imce_rename_prevalidate(&$form, &$form_state) { + if ($form_state['values']['filenames'] == '__IS_DIR__') { + $form_state['build_info']['args'][0]['imce']['files']['__IS_DIR__'] = '__IS_DIR__'; //add a fake file so that validation will pass + }; +} + +/** + * Submit rename form. + */ +function imce_rename_submit($form, &$form_state) { + $form_state['redirect'] = FALSE; + $imce =& $form_state['build_info']['args'][0]['imce']; + imce_process_files($form_state['values']['filenames'], $imce, 'imce_rename_callback', array($form_state['values']['new_name'])); +} + +/** + * Rename a a file or a directory + */ +function imce_rename_callback($old_name, &$imce, $new_name) { + if ($old_name == '__IS_DIR__') { + $old_uri = imce_dir_uri($imce); + $new_uri = $imce['scheme'] . '://' . $new_name .'/'; + imce_rename_dir($imce, $old_uri, $new_uri); + } + else { + $extension = substr($old_name, -4); + if (strtolower(substr($new_name, -4)) != strtolower($extension)) { + $new_name .= $extension; + } + + $old_uri = imce_dir_uri($imce) . $old_name; + $new_uri = imce_dir_uri($imce) . $new_name; + + imce_rename_file($imce, $old_uri, $new_uri); + } +} + +/** + * Rename a file + */ +function imce_rename_file(&$imce, $old_uri, $new_uri) { + $result = db_query("SELECT f.* FROM {file_managed} f WHERE f.uri = :uri", array(':uri' => $old_uri)); + $file = $result->fetchObject(); + + $move = file_move($file, $new_uri, FILE_EXISTS_ERROR); + + $file->uri = $new_uri; + $file->filename = basename($file->uri); + $img = imce_image_info($file->uri); + $file->width = $img['width']; + $file->height = $img['height']; + + if ($move) { + drupal_set_message(t('Rename successful! Renamed "@old_file" to "@new_file"', array('@old_file' => utf8_encode(basename($old_uri)), '@new_file' => utf8_encode(basename($new_uri))))); + return $file; + } + else { + drupal_set_message(t('Failed to rename file "@old_file" to "@new_file" because "@new_file" already exists', array('@old_file' => utf8_encode(basename($old_uri)), '@new_file' => utf8_encode(basename($new_uri))))); + } +} + +/** + * Rename a directory + */ +function imce_rename_dir(&$imce, $old_uri, $new_uri) { + $rename = @rename(drupal_realpath($old_uri), drupal_realpath($new_uri)); + if ($rename) { + $result = db_query("SELECT f.* FROM {file_managed} f WHERE f.uri LIKE :old", array(':old' => $old_uri .'%')); + foreach ($result as $file) { + $file->uri = str_replace($old_uri, $new_uri, $file->uri); + drupal_write_record('file_managed', $file, array('fid')); + } + + drupal_set_message(t('Rename successful! Renamed "@old_dir" to "@new_dir"', array('@old_dir' => utf8_encode($old_uri), '@new_dir' => utf8_encode($new_uri)))); + } + else { + drupal_set_message(t('Failed to rename directory "@old_dir" to "@new_dir"', array('@old_dir' => utf8_encode($old_uri), '@new_dir' => utf8_encode($new_uri)))); + } + + return $file; +} + +/** + * Ajax operation: rename + */ +function imce_js_rename(&$imce) { + if ($imce['perm']['rename']) { + $_POST['op'] = t('Rename'); + return imce_process_fileop($imce); + } +} \ No newline at end of file diff --git a/sites/all/modules/imce_rename/rename.png b/sites/all/modules/imce_rename/rename.png new file mode 100644 index 0000000000000000000000000000000000000000..ba83ecab01a1b511264698a627c79720edf32cb5 GIT binary patch literal 397 zcmeAS@N?(olHy`uVBq!ia0y~yU=RRd4mJh`2Kmqb6B!s7*h@TpUD<DO330Ir{#zsP zkAZ=Kv%n*=n1R7h0fZUFYG>YKU|?WLcl32+VA$Bt{U?!?fq_xR)5S5Q;?~k&-TcD_ z0<|ldc-WYDdAXR_*qDDaFFUy)!9Ka5AR)nCaYMp^1qurk5@zv$Wx2VynAvz%-F;K* z(*4|I;<qJ}i{2NNzn?eh$&b1t^#-#)1;u86dMLN@p2VeJQ+F*2H&8rr{PJh+*f`yn z*8kTm?Y`QV$7Q#w=`GKi)CW!rviSN=oLHk9G|%wFoZkBr^#j)O7MVN5)#!#if4hPG zW~A8D+y|9X*%|k5$$g(3{d&sgeYYZSe33Rh_e*mlV_o!`h4*Wm9N)Y%`2M|}%ZmTd zTj#7bZ$GcR866YO-m~z=^>?d<FWh?2I5p#$P-~Kh+CT1)X<T!-O`>~u|BgPdT5luK wR26fuT0ND~P&{DOtE^yAo}@`l!9N%zSZCefbkf+$z`(%Z>FVdQ&MBb@01By|@Bjb+ literal 0 HcmV?d00001 -- GitLab