From 1f0e77421e974e98cc1cd634b171c20158dfa2dc Mon Sep 17 00:00:00 2001 From: Marcin Haba Date: Fri, 11 Dec 2015 08:56:58 +0100 Subject: [PATCH] baculum: Add run job again button and small improvements --- .../protected/JavaScript/slide-window.js | 129 +++++++++++++--- gui/baculum/protected/Pages/API/FileSets.php | 2 +- gui/baculum/protected/Pages/API/JobRun.php | 15 +- gui/baculum/protected/Pages/API/JobShow.php | 38 +++++ gui/baculum/protected/Pages/API/JobsShow.php | 32 ++++ gui/baculum/protected/Pages/Home.page | 142 ++++++++++++++++-- gui/baculum/protected/Portlets/ClientList.tpl | 2 +- .../protected/Portlets/JobConfiguration.php | 95 +++++++++--- gui/baculum/protected/Portlets/JobList.php | 18 ++- gui/baculum/protected/Portlets/JobList.tpl | 30 +++- gui/baculum/protected/Portlets/JobRunList.tpl | 2 +- gui/baculum/protected/Portlets/PoolList.tpl | 2 +- .../protected/Portlets/StorageList.tpl | 2 +- gui/baculum/protected/application.xml | 2 + .../themes/Baculum-v1/loader-alter.gif | Bin 0 -> 23528 bytes gui/baculum/themes/Baculum-v1/loader.gif | Bin 0 -> 23523 bytes gui/baculum/themes/Baculum-v1/play.png | Bin 0 -> 1830 bytes gui/baculum/themes/Baculum-v1/style.css | 31 +++- 18 files changed, 472 insertions(+), 70 deletions(-) create mode 100644 gui/baculum/protected/Pages/API/JobShow.php create mode 100644 gui/baculum/protected/Pages/API/JobsShow.php create mode 100644 gui/baculum/themes/Baculum-v1/loader-alter.gif create mode 100644 gui/baculum/themes/Baculum-v1/loader.gif create mode 100644 gui/baculum/themes/Baculum-v1/play.png diff --git a/gui/baculum/protected/JavaScript/slide-window.js b/gui/baculum/protected/JavaScript/slide-window.js index e8b1325c71..b857b7392a 100644 --- a/gui/baculum/protected/JavaScript/slide-window.js +++ b/gui/baculum/protected/JavaScript/slide-window.js @@ -12,6 +12,7 @@ var SlideWindowClass = Class.create({ options: null, configurationObj: null, loadRequest : null, + actionsRequest: null, repeaterEl: null, gridEl: null, checked: [], @@ -29,16 +30,19 @@ var SlideWindowClass = Class.create({ }, elements : { - containerSuffix : '-slide-window-container', - configurationWindows : 'div.configuration', + content: 'div.slide-window-content', + containerSuffix: '-slide-window-container', + containerProgressSuffix: '-slide-window-progress', + configurationWindows: 'div.configuration', configurationProgress: 'div.configuration-progress', - contentItems : 'slide-window-element', - contentAlternatingItems : 'slide-window-element-alternating', - toolsButtonSuffix : '-slide-window-tools', - optionsButtonSuffix : '-slide-window-options', - actionsSuffix : '-slide-window-actions', - toolbarSuffix : '-slide-window-toolbar', - titleSuffix : '-slide-window-title' + contentItems: 'slide-window-element', + contentAlternatingItems: 'slide-window-element-alternating', + toolsButtonSuffix: '-slide-window-tools', + optionsButtonSuffix: '-slide-window-options', + actionsSuffix: '-slide-window-actions', + toolbarSuffix: '-slide-window-toolbar', + titleSuffix: '-slide-window-title', + actionsButton : 'actions_btn' }, initialize: function(windowId, data) { @@ -128,8 +132,28 @@ var SlideWindowClass = Class.create({ this.options.observe('click', function() { this.toggleToolbar(); }.bind(this)); + + this.setActionsBtnEvents(); + }, + + setActionsBtnEvents: function() { + var actions_btn_container = this.window.getElementsByClassName(this.elements.actionsButton); + if (actions_btn_container.length === 1) { + var actions_btn = actions_btn_container[0].getElementsByTagName('INPUT'); + if (actions_btn.length === 1) { + actions_btn[0].addEventListener('mouseup', function(e) { + var row = this.getGridRowUnderCursor(e); + var el = $(row).down('input[type=hidden]'); + if(el) { + var val = el.getValue(); + this.actionsRequest.ActiveControl.CallbackParameter = val; + this.actionsRequest.dispatch(); + } + }.bind(this)); + } + } }, - + openWindow : function() { this.hideOtherWindows(); Effect.toggle(this.window, 'slide', { duration: 0.3, afterFinish : function() { @@ -148,7 +172,16 @@ var SlideWindowClass = Class.create({ isWindowOpen: function() { return !(this.window.style.display === 'none'); }, - + + showProgress: function(show) { + var progress = $(this.windowId + this.elements.containerProgressSuffix); + if (show === true) { + progress.setStyle({display: 'block'}); + } else if (show === false) { + progress.hide(); + } + }, + resetSize : function() { if(this.isConfigurationOpen()) { if(this.isFullSize()) { @@ -210,10 +243,14 @@ var SlideWindowClass = Class.create({ this.configurationObj = obj; }, - setWindowElementsEvent: function(repeaterEl, gridEl, requestObj) { - this.repeaterEl = repeaterEl; - this.gridEl = gridEl; - this.loadRequest = requestObj; + setWindowElementsEvent: function(opts) { + this.repeaterEl = opts.repeater_id; + this.gridEl = opts.grid_id; + this.loadRequest = opts.request_obj; + if (opts.hasOwnProperty('actions_obj')) { + this.actionsRequest = opts.actions_obj; + } + this.showProgress(false); this.markAllChecked(false); this.setLoadRequest(); this.postWindowOpen(); @@ -228,6 +265,15 @@ var SlideWindowClass = Class.create({ dataList = $(this.repeaterEl + '_Container').select('div.slide-window-element'); } + var set_callback_parameter = function(element) { + var el = $(element).down('input[type=hidden]') + if(el) { + var val = el.getValue(); + this.loadRequest.ActiveControl.CallbackParameter = val; + this.loadRequest.dispatch(); + this.configurationObj.openConfigurationWindow(this); + } + }.bind(this); dataList.each(function(tr) { $(tr).observe('click', function(index, clickedEl) { var target = clickedEl.target || clickedEl.srcElement; @@ -236,14 +282,7 @@ var SlideWindowClass = Class.create({ if(clicked && clicked.hasAttribute('type') && clicked.readAttribute('type') == 'checkbox') { return; } - - var el = $(tr).down('input[type=hidden]') - if(el) { - var val = el.getValue(); - this.loadRequest.ActiveControl.CallbackParameter = val; - this.loadRequest.dispatch(); - this.configurationObj.openConfigurationWindow(this); - } + set_callback_parameter(tr); }.bind(this, tr)); }.bind(this)); }, @@ -445,6 +484,48 @@ var SlideWindowClass = Class.create({ postWindowOpen: function() { this.setActions(); this.setElementsCount(); + this.setOptionsBtn(); + }, + setOptionsBtn: function() { + var options_btn = this.window.getElementsByClassName(this.elements.actionsButton); + var table_window = $(this.windowId + this.elements.containerSuffix).down(this.elements.content); + if (options_btn.length === 1) { + options_btn = options_btn[0]; + table_window.stopObserving('mouseover'); + table_window.observe('mouseover', function(e) { + var el = this.getGridRowUnderCursor(e); + if (el && (el.className == this.elements.contentItems || el.className == this.elements.contentAlternatingItems)) { + el.style.backgroundColor = '#aeb2b6'; + options_btn.setStyle({display: ''}); + var scroll_y = document.viewport.getScrollOffsets().top; + var y = (el.viewportOffset().top + scroll_y - 57).toString() + 'px'; + options_btn.setStyle({top: y}); + } else { + options_btn.setStyle({display: 'none'}); + } + }.bind(this)); + table_window.stopObserving('mouseout'); + table_window.observe('mouseout', function(e) { + table_window.select('TR').forEach(function(el) { + el.style.backgroundColor = ''; + });; + options_btn.setStyle({display: 'none'}); + }); + } + }, + getGridRowUnderCursor: function(e) { + var x = e.clientX - 100; + var y = e.clientY; + var element_mouse_is_over = document.elementFromPoint(x, y); + var el; + var el_over = $(element_mouse_is_over); + if (el_over && el_over.nodeName != 'TR') { + el = el_over.down('tr'); + if (!el) { + el = el_over.up('tr'); + } + } + return el; } }); @@ -452,7 +533,7 @@ var SlideWindow = new SlideWindowClass() document.observe("dom:loaded", function() { if(Prototype.Browser.IE || Prototype.Browser.Gecko || Prototype.Browser.WebKit) { - $$('input[type=checkbox], input[type=submit], input[type=radio], a').each(function(el) { + $$('input[type=checkbox], input[type=submit], input[type=radio], input[type=image], a').each(function(el) { el.observe('focus', function() { el.blur(); }.bind(el)); diff --git a/gui/baculum/protected/Pages/API/FileSets.php b/gui/baculum/protected/Pages/API/FileSets.php index 5f2ce3f1d0..b5275c140d 100644 --- a/gui/baculum/protected/Pages/API/FileSets.php +++ b/gui/baculum/protected/Pages/API/FileSets.php @@ -43,4 +43,4 @@ class FileSets extends BaculumAPI { } } } -?> \ No newline at end of file +?> diff --git a/gui/baculum/protected/Pages/API/JobRun.php b/gui/baculum/protected/Pages/API/JobRun.php index a9c950faa3..e895bf48c3 100644 --- a/gui/baculum/protected/Pages/API/JobRun.php +++ b/gui/baculum/protected/Pages/API/JobRun.php @@ -48,7 +48,20 @@ class JobRun extends BaculumAPI { if(!is_null($storage)) { if(!is_null($pool)) { $joblevels = $this->getModule('misc')->getJobLevels(); - $run = $this->getModule('bconsole')->bconsoleCommand($this->director, array('run', 'job="' . $job . '"', 'level="' . $joblevels[$level] . '"', 'fileset="' . $fileset . '"', 'client="' . $client->name . '"', 'storage="' . $storage->name . '"', 'pool="' . $pool->name . '"' , 'priority="' . $priority . '"', $jobid , $verifyjob, 'yes'), $this->user); + $command = array( + 'run', + 'job="' . $job . '"', + 'level="' . $joblevels[$level] . '"', + 'fileset="' . $fileset . '"', + 'client="' . $client->name . '"', + 'storage="' . $storage->name . '"', + 'pool="' . $pool->name . '"' , + 'priority="' . $priority . '"', + $jobid, + $verifyjob, + 'yes' + ); + $run = $this->getModule('bconsole')->bconsoleCommand($this->director, $command, $this->user); $this->output = $run->output; $this->error = (integer)$run->exitcode; } else { diff --git a/gui/baculum/protected/Pages/API/JobShow.php b/gui/baculum/protected/Pages/API/JobShow.php new file mode 100644 index 0000000000..fddd516c95 --- /dev/null +++ b/gui/baculum/protected/Pages/API/JobShow.php @@ -0,0 +1,38 @@ +Request['id']); + $job = $this->getModule('job')->getJobById($jobid); + if(!is_null($job)) { + $jobShow = $this->getModule('bconsole')->bconsoleCommand($this->director, array('show', 'job="' . $job->name . '"'), $this->user); + $this->output = $jobShow->output; + $this->error = (integer)$jobShow->exitcode; + } else { + $this->output = JobError::MSG_ERROR_JOB_DOES_NOT_EXISTS; + $this->error = JobError::ERROR_JOB_DOES_NOT_EXISTS; + } + } +} + +?> diff --git a/gui/baculum/protected/Pages/API/JobsShow.php b/gui/baculum/protected/Pages/API/JobsShow.php new file mode 100644 index 0000000000..988067914a --- /dev/null +++ b/gui/baculum/protected/Pages/API/JobsShow.php @@ -0,0 +1,32 @@ +getModule('bconsole')->bconsoleCommand($this->director, array('show', 'jobs'), $this->user); + $this->output = $jobs->output; + $this->error = (integer)$jobs->exitcode; + } +} + +?> diff --git a/gui/baculum/protected/Pages/Home.page b/gui/baculum/protected/Pages/Home.page index 4aef694f0e..f0f5b9880f 100644 --- a/gui/baculum/protected/Pages/Home.page +++ b/gui/baculum/protected/Pages/Home.page @@ -13,15 +13,139 @@
diff --git a/gui/baculum/protected/Portlets/ClientList.tpl b/gui/baculum/protected/Portlets/ClientList.tpl index eb5b85b9af..5ee46995ca 100644 --- a/gui/baculum/protected/Portlets/ClientList.tpl +++ b/gui/baculum/protected/Portlets/ClientList.tpl @@ -17,7 +17,7 @@ AllowSorting="false" OnSortCommand="sortDataGrid" CellPadding="5px" - CssClass="window-section-detail" + CssClass="window-section-detail-smallrow" ItemStyle.CssClass="slide-window-element" AlternatingItemStyle.CssClass="slide-window-element-alternating" > diff --git a/gui/baculum/protected/Portlets/JobConfiguration.php b/gui/baculum/protected/Portlets/JobConfiguration.php index 0be1ad5c71..35c3c0fd09 100644 --- a/gui/baculum/protected/Portlets/JobConfiguration.php +++ b/gui/baculum/protected/Portlets/JobConfiguration.php @@ -28,6 +28,7 @@ class JobConfiguration extends Portlets { const DEFAULT_JOB_PRIORITY = 10; + const RESOURCE_SHOW_PATTERN = '/^\s+--> %resource: name=(.+?(?=\s\S+\=.+)|.+$)/i'; public $jobToVerify = array('C', 'O', 'd'); @@ -100,12 +101,21 @@ class JobConfiguration extends Portlets { $this->Pool->SelectedValue = $jobdata->poolid; $this->Pool->dataBind(); - $storages = $this->Application->getModule('api')->get(array('storages'))->output; + $jobshow = $this->Application->getModule('api')->get(array('jobs', 'show', $jobdata->jobid))->output; + $storageShow = $this->getResourceName('storage', $jobshow); $storagesList = array(); + $selectedStorageId = null; + $storages = $this->Application->getModule('api')->get(array('storages'))->output; foreach($storages as $storage) { + if ($storage->name == $storageShow) { + $selectedStorageId = $storage->storageid; + } $storagesList[$storage->storageid] = $storage->name; } $this->Storage->dataSource = $storagesList; + if (!is_null($selectedStorageId)) { + $this->Storage->SelectedValue = $selectedStorageId; + } $this->Storage->dataBind(); $runningJobStates = $this->Application->getModule('misc')->getRunningJobStates(); @@ -150,26 +160,41 @@ class JobConfiguration extends Portlets { if($this->PriorityValidator->IsValid === false) { return false; } + $params = array(); - $params['id'] = $this->JobID->Text; - $params['level'] = $this->Level->SelectedValue; - $params['fileset'] = $this->FileSet->SelectedValue; - $params['clientid'] = $this->Client->SelectedValue; - $params['storageid'] = $this->Storage->SelectedValue; - $params['poolid'] = $this->Pool->SelectedValue; - $params['priority'] = $this->Priority->Text; - - if (in_array($this->Level->SelectedItem->Value, $this->jobToVerify)) { - $verifyVals = $this->getVerifyVals(); - if ($this->JobToVerifyOptions->SelectedItem->Value == $verifyVals['jobname']) { - $params['verifyjob'] = $this->JobToVerifyJobName->SelectedValue; - } elseif ($this->JobToVerifyOptions->SelectedItem->Value == $verifyVals['jobid']) { - $params['jobid'] = $this->JobToVerifyJobId->Text; + if (is_null($sender) && is_numeric($param)) { + $jobdata = $this->Application->getModule('api')->get(array('jobs', $param))->output; + $jobshow = $this->Application->getModule('api')->get(array('jobs', 'show', $jobdata->jobid))->output; + $params['id'] = $jobdata->jobid; + $params['level'] = $jobdata->level; + $params['fileset'] = $this->getResourceName('fileset', $jobshow); + $params['clientid'] = $jobdata->clientid; + $storage = $this->getResourceName('storage', $jobshow); + $params['storageid'] = $this->getStorageByName($storage)->storageid; + $pool = $this->getResourceName('pool', $jobshow); + $params['poolid'] = $this->getPoolByName($pool)->poolid; + } else { + $params['id'] = $this->JobID->Text; + $params['level'] = $this->Level->SelectedValue; + $params['fileset'] = $this->FileSet->SelectedValue; + $params['clientid'] = $this->Client->SelectedValue; + $params['storageid'] = $this->Storage->SelectedValue; + $params['poolid'] = $this->Pool->SelectedValue; + $params['priority'] = $this->Priority->Text; + + if (in_array($this->Level->SelectedItem->Value, $this->jobToVerify)) { + $verifyVals = $this->getVerifyVals(); + if ($this->JobToVerifyOptions->SelectedItem->Value == $verifyVals['jobname']) { + $params['verifyjob'] = $this->JobToVerifyJobName->SelectedValue; + } elseif ($this->JobToVerifyOptions->SelectedItem->Value == $verifyVals['jobid']) { + $params['jobid'] = $this->JobToVerifyJobId->Text; + } } } - $result = $this->Application->getModule('api')->create(array('jobs', 'run'), $params)->output; - $this->Estimation->Text = implode(PHP_EOL, $result); + if (!is_null($sender) || !is_numeric($param)) { + $this->Estimation->Text = implode(PHP_EOL, $result); + } } public function estimate($sender, $param) { @@ -204,5 +229,41 @@ class JobConfiguration extends Portlets { $verifyVals = array_combine($verifyOpt, $verifyOpt); return $verifyVals; } + + private function getResourceName($resource, $jobshow) { + $resource_name = null; + $pattern = str_replace('%resource', $resource, self::RESOURCE_SHOW_PATTERN); + for ($i = 0; $i < count($jobshow); $i++) { + if (preg_match($pattern, $jobshow[$i], $match) === 1) { + $resource_name = $match[1]; + break; + } + } + return $resource_name; + } + + private function getPoolByName($name) { + $pool = null; + $pools = $this->Application->getModule('api')->get(array('pools'))->output; + for ($i = 0; $i < count($pools); $i++) { + if ($pools[$i]->name == $name) { + $pool = $pools[$i]; + break; + } + } + return $pool; + } + + private function getStorageByName($name) { + $storage = null; + $storages = $this->Application->getModule('api')->get(array('storages'))->output; + for ($i = 0; $i < count($storages); $i++) { + if ($storages[$i]->name == $name) { + $storage = $storages[$i]; + break; + } + } + return $storage; + } } ?> diff --git a/gui/baculum/protected/Portlets/JobList.php b/gui/baculum/protected/Portlets/JobList.php index ded04a7ba1..3e5e7994ac 100644 --- a/gui/baculum/protected/Portlets/JobList.php +++ b/gui/baculum/protected/Portlets/JobList.php @@ -22,7 +22,6 @@ Prado::using('System.Web.UI.ActiveControls.TActiveDataGrid'); Prado::using('System.Web.UI.ActiveControls.TActiveRepeater'); -Prado::using('System.Web.UI.ActiveControls.TActiveLinkButton'); Prado::using('System.Web.UI.ActiveControls.TActivePanel'); Prado::using('System.Web.UI.ActiveControls.TCallback'); Prado::using('Application.Portlets.ISlideWindow'); @@ -35,6 +34,7 @@ class JobList extends Portlets implements ISlideWindow { public $windowTitle; public $jobLevels; public $jobStates; + public $runningJobStates; public $jobTypes; public function setID($id) { @@ -63,15 +63,21 @@ class JobList extends Portlets implements ISlideWindow { public function onLoad($param) { parent::onLoad($param); - $this->prepareData(); + $allowedButtons = array('JobBtn', 'ReloadJobs', 'Run', 'RunJobAgain'); + if($this->Page->IsPostBack || $this->Page->IsCallBack) { + if(in_array($this->getPage()->CallBackEventTarget->ID, $allowedButtons)) { + $this->prepareData(); + } + } $misc = $this->Application->getModule('misc'); $this->jobLevels = $misc->getJobLevels(); $this->jobStates = $misc->getJobState(); $this->jobTypes = $misc->getJobType(); + $this->runningJobStates = $misc->getRunningJobStates(); } public function prepareData($forceReload = false) { - $allowedButtons = array('JobBtn', 'ReloadJobs', 'Run'); + $allowedButtons = array('JobBtn', 'ReloadJobs', 'Run', 'RunJobAgain'); if($this->Page->IsPostBack || $this->Page->IsCallBack || $forceReload) { if(in_array($this->getPage()->CallBackEventTarget->ID, $allowedButtons) || $forceReload) { $params = $this->getUrlParams('jobs', $this->getPage()->JobWindow->ID); @@ -106,6 +112,12 @@ class JobList extends Portlets implements ISlideWindow { } } + public function run_again($sender, $param) { + if($this->Page->IsCallBack) { + $this->getPage()->JobConfiguration->run_again(null, $param->CallbackParameter); + } + } + public function executeAction($action) { $params = explode(';', $this->CheckedValues->Value); $commands = array(); diff --git a/gui/baculum/protected/Portlets/JobList.tpl b/gui/baculum/protected/Portlets/JobList.tpl index 7e20d226e9..54b24f965e 100644 --- a/gui/baculum/protected/Portlets/JobList.tpl +++ b/gui/baculum/protected/Portlets/JobList.tpl @@ -53,11 +53,12 @@
<%=isset($this->getPage()->JobWindow->jobStates[$this->getParent()->Data['jobstatus']]['value']) ? $this->getPage()->JobWindow->jobStates[$this->getParent()->Data['jobstatus']]['value'] : ''%>
- + + + <%=$this->getParent()->Data['endtime']%> + <%=in_array($this->getParent()->Data['jobstatus'], $this->getPage()->JobWindow->runningJobStates) ? '' : ''%> + + @@ -68,4 +69,23 @@ status_callback_func(); + + + var img_btn = $('run_job_again_btn'); + var img_src_path = img_btn.readAttribute('src').replace(/[^\/]+\S$/, ''); + img_btn.writeAttribute('disabled', 'disabled'); + img_btn.writeAttribute('src', img_src_path + 'loader.gif'); + + + var img_btn = $('run_job_again_btn'); + var img_src_path = img_btn.readAttribute('src').replace(/[^\/]+\S$/, ''); + img_btn.writeAttribute('src', img_src_path + 'play.png'); + img_btn.removeAttribute('disabled'); + status_callback_func(); + oMonitor(); + + + diff --git a/gui/baculum/protected/Portlets/JobRunList.tpl b/gui/baculum/protected/Portlets/JobRunList.tpl index ec4255e100..32659d798a 100644 --- a/gui/baculum/protected/Portlets/JobRunList.tpl +++ b/gui/baculum/protected/Portlets/JobRunList.tpl @@ -20,7 +20,7 @@ AllowSorting="false" OnSortCommand="sortDataGrid" CellPadding="5px" - CssClass="window-section-detail" + CssClass="window-section-detail-smallrow" ItemStyle.CssClass="slide-window-element" AlternatingItemStyle.CssClass="slide-window-element-alternating" > diff --git a/gui/baculum/protected/Portlets/PoolList.tpl b/gui/baculum/protected/Portlets/PoolList.tpl index fa147f84d3..d0193a1447 100644 --- a/gui/baculum/protected/Portlets/PoolList.tpl +++ b/gui/baculum/protected/Portlets/PoolList.tpl @@ -18,7 +18,7 @@ AllowSorting="false" OnSortCommand="sortDataGrid" CellPadding="5px" - CssClass="window-section-detail" + CssClass="window-section-detail-smallrow" ItemStyle.CssClass="slide-window-element" AlternatingItemStyle.CssClass="slide-window-element-alternating" > diff --git a/gui/baculum/protected/Portlets/StorageList.tpl b/gui/baculum/protected/Portlets/StorageList.tpl index cf0649bfa2..54a71925a2 100644 --- a/gui/baculum/protected/Portlets/StorageList.tpl +++ b/gui/baculum/protected/Portlets/StorageList.tpl @@ -17,7 +17,7 @@ AllowSorting="false" OnSortCommand="sortDataGrid" CellPadding="5px" - CssClass="window-section-detail" + CssClass="window-section-detail-smallrow" ItemStyle.CssClass="slide-window-element" AlternatingItemStyle.CssClass="slide-window-element-alternating" > diff --git a/gui/baculum/protected/application.xml b/gui/baculum/protected/application.xml index 116597d0f4..99e3f67717 100644 --- a/gui/baculum/protected/application.xml +++ b/gui/baculum/protected/application.xml @@ -63,6 +63,8 @@ + + diff --git a/gui/baculum/themes/Baculum-v1/loader-alter.gif b/gui/baculum/themes/Baculum-v1/loader-alter.gif new file mode 100644 index 0000000000000000000000000000000000000000..87dd7fafabfa4ed5b40019d343899ae353f7e376 GIT binary patch literal 23528 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