Spade
Mini Shell
| Directory:~$ /home/lmsyaran/public_html/joomla4/ |
| [Home] [System Details] [Kill Me] |
PK�6�[�]����boxpacker/Box.phpnu�[���<?php
/**
* @package HikaShop for Joomla!
* @version 4.4.1
* @author hikashop.com
* @copyright (C) 2010-2021 HIKARI SOFTWARE. All rights reserved.
* @license GNU/GPLv3 http://www.gnu.org/licenses/gpl-3.0.html
*/
defined('_JEXEC') or die('Restricted access');
?><?php
namespace DVDoug\BoxPacker;
interface Box
{
public function getReference();
public function getOuterWidth();
public function getOuterLength();
public function getOuterDepth();
public function getEmptyWeight();
public function getInnerWidth();
public function getInnerLength();
public function getInnerDepth();
public function getInnerVolume();
public function getMaxWeight();
}
PK�6�[~MR��boxpacker/BoxList.phpnu�[���<?php
/**
* @package HikaShop for Joomla!
* @version 4.4.1
* @author hikashop.com
* @copyright (C) 2010-2021 HIKARI SOFTWARE. All rights reserved.
* @license GNU/GPLv3 http://www.gnu.org/licenses/gpl-3.0.html
*/
defined('_JEXEC') or die('Restricted access');
?><?php
namespace DVDoug\BoxPacker;
class BoxList extends \SplMinHeap
{
public function compare($boxA, $boxB)
{
$boxAVolume = $boxA->getInnerWidth() *
$boxA->getInnerLength() * $boxA->getInnerDepth();
$boxBVolume = $boxB->getInnerWidth() *
$boxB->getInnerLength() * $boxB->getInnerDepth();
if ($boxBVolume > $boxAVolume) {
return 1;
}
if ($boxAVolume > $boxBVolume) {
return -1;
}
if ($boxB->getEmptyWeight() > $boxA->getEmptyWeight()) {
return 1;
}
if ($boxA->getEmptyWeight() > $boxB->getEmptyWeight()) {
return -1;
}
if ($boxB->getMaxWeight() > $boxA->getMaxWeight()) {
return 1;
}
if ($boxA->getMaxWeight() > $boxB->getMaxWeight()) {
return -1;
}
return 0;
}
}
PK�6�[�Ywܷ�boxpacker/ConstrainedItem.phpnu�[���<?php
/**
* @package HikaShop for Joomla!
* @version 4.4.1
* @author hikashop.com
* @copyright (C) 2010-2021 HIKARI SOFTWARE. All rights reserved.
* @license GNU/GPLv3 http://www.gnu.org/licenses/gpl-3.0.html
*/
defined('_JEXEC') or die('Restricted access');
?><?php
namespace DVDoug\BoxPacker;
interface ConstrainedItem extends Item
{
public function canBePackedInBox(ItemList $alreadyPackedItems, Box
$box);
}
PK�6�[Ǟ��MM&boxpacker/ConstrainedPlacementItem.phpnu�[���<?php
/**
* @package HikaShop for Joomla!
* @version 4.4.1
* @author hikashop.com
* @copyright (C) 2010-2021 HIKARI SOFTWARE. All rights reserved.
* @license GNU/GPLv3 http://www.gnu.org/licenses/gpl-3.0.html
*/
defined('_JEXEC') or die('Restricted access');
?><?php
namespace DVDoug\BoxPacker;
interface ConstrainedPlacementItem extends Item
{
public function canBePacked(
Box $box,
PackedItemList $alreadyPackedItems,
$proposedX,
$proposedY,
$proposedZ,
$width,
$length,
$depth
);
}
PK�6�[�i�#boxpacker/index.htmlnu�[���<html><body></body></html>
PK�6�[Fh QQboxpacker/Item.phpnu�[���<?php
/**
* @package HikaShop for Joomla!
* @version 4.4.1
* @author hikashop.com
* @copyright (C) 2010-2021 HIKARI SOFTWARE. All rights reserved.
* @license GNU/GPLv3 http://www.gnu.org/licenses/gpl-3.0.html
*/
defined('_JEXEC') or die('Restricted access');
?><?php
namespace DVDoug\BoxPacker;
interface Item
{
public function getDescription();
public function getWidth();
public function getLength();
public function getDepth();
public function getWeight();
public function getVolume();
public function getKeepFlat();
}
PK�6�[ �QQboxpacker/ItemList.phpnu�[���<?php
/**
* @package HikaShop for Joomla!
* @version 4.4.1
* @author hikashop.com
* @copyright (C) 2010-2021 HIKARI SOFTWARE. All rights reserved.
* @license GNU/GPLv3 http://www.gnu.org/licenses/gpl-3.0.html
*/
defined('_JEXEC') or die('Restricted access');
?><?php
namespace DVDoug\BoxPacker;
class ItemList extends \SplMaxHeap
{
public function compare($itemA, $itemB)
{
if ($itemA->getVolume() > $itemB->getVolume()) {
return 1;
} elseif ($itemA->getVolume() < $itemB->getVolume()) {
return -1;
} elseif ($itemA->getWeight() !== $itemB->getWeight()) {
return $itemA->getWeight() - $itemB->getWeight();
} elseif ($itemA->getDescription() <
$itemB->getDescription()) {
return 1;
} else {
return -1;
}
}
public function asArray()
{
$return = [];
foreach (clone $this as $item) {
$return[] = $item;
}
return $return;
}
public function topN($n)
{
$workingList = clone $this;
$topNList = new self();
$i = 0;
while(!$workingList->isEmpty() && $i < $n) {
$topNList->insert($workingList->extract());
$i++;
}
return $topNList;
}
public function remove(Item $item)
{
$workingSet = [];
while (!$this->isEmpty()) {
$workingSet[] = $this->extract();
}
$removed = false; // there can be multiple identical items, ensure
that only 1 is removed
foreach ($workingSet as $workingSetItem) {
if (!$removed && $workingSetItem === $item) {
$removed = true;
} else {
$this->insert($workingSetItem);
}
}
}
}
PK�6�[Fh���#boxpacker/ItemTooLargeException.phpnu�[���<?php
/**
* @package HikaShop for Joomla!
* @version 4.4.1
* @author hikashop.com
* @copyright (C) 2010-2021 HIKARI SOFTWARE. All rights reserved.
* @license GNU/GPLv3 http://www.gnu.org/licenses/gpl-3.0.html
*/
defined('_JEXEC') or die('Restricted access');
?><?php
namespace DVDoug\BoxPacker;
use RuntimeException;
class ItemTooLargeException extends RuntimeException
{
public $item;
public function __construct($message, Item $item)
{
$this->item = $item;
parent::__construct($message);
}
public function getItem()
{
return $this->item;
}
}
PK�6�[|\O�llboxpacker/LayerStabiliser.phpnu�[���<?php
/**
* @package HikaShop for Joomla!
* @version 4.4.1
* @author hikashop.com
* @copyright (C) 2010-2021 HIKARI SOFTWARE. All rights reserved.
* @license GNU/GPLv3 http://www.gnu.org/licenses/gpl-3.0.html
*/
defined('_JEXEC') or die('Restricted access');
?><?php
namespace DVDoug\BoxPacker;
use Psr\Log\LoggerAwareInterface;
use Psr\Log\LoggerAwareTrait;
use Psr\Log\NullLogger;
class LayerStabiliser implements LoggerAwareInterface
{
use LoggerAwareTrait;
public function __construct()
{
$this->logger = new NullLogger();
}
public function stabilise(array $packedLayers)
{
$stabilisedLayers = [];
usort($packedLayers, [$this, 'compare']);
$currentZ = 0;
foreach ($packedLayers as $oldZLayer) {
$oldZStart = $oldZLayer->getStartDepth();
$newZLayer = new PackedLayer();
foreach ($oldZLayer->getItems() as $oldZItem) {
$newZ = $oldZItem->getZ() - $oldZStart + $currentZ;
$newZItem = new PackedItem($oldZItem->getItem(),
$oldZItem->getX(), $oldZItem->getY(), $newZ,
$oldZItem->getWidth(), $oldZItem->getLength(),
$oldZItem->getDepth());
$newZLayer->insert($newZItem);
}
$stabilisedLayers[] = $newZLayer;
$currentZ += $newZLayer->getDepth();
}
return $stabilisedLayers;
}
private function compare(PackedLayer $layerA, PackedLayer $layerB)
{
return ($layerB->getFootprint() - $layerA->getFootprint()) ?:
($layerB->getDepth() - $layerA->getDepth());
}
}
PK�6�[]���DDboxpacker/OrientatedItem.phpnu�[���<?php
/**
* @package HikaShop for Joomla!
* @version 4.4.1
* @author hikashop.com
* @copyright (C) 2010-2021 HIKARI SOFTWARE. All rights reserved.
* @license GNU/GPLv3 http://www.gnu.org/licenses/gpl-3.0.html
*/
defined('_JEXEC') or die('Restricted access');
?><?php
namespace DVDoug\BoxPacker;
use JsonSerializable;
class OrientatedItem implements JsonSerializable
{
protected $item;
protected $width;
protected $length;
protected $depth;
protected static $tippingPointCache = [];
public function __construct(Item $item, $width, $length, $depth)
{
$this->item = $item;
$this->width = $width;
$this->length = $length;
$this->depth = $depth;
}
public function getItem()
{
return $this->item;
}
public function getWidth()
{
return $this->width;
}
public function getLength()
{
return $this->length;
}
public function getDepth()
{
return $this->depth;
}
public function getSurfaceFootprint()
{
return $this->width * $this->length;
}
public function getTippingPoint()
{
$cacheKey = $this->width . '|' . $this->length .
'|' . $this->depth;
if (isset(static::$tippingPointCache[$cacheKey])) {
$tippingPoint = static::$tippingPointCache[$cacheKey];
} else {
$tippingPoint = atan(min($this->length, $this->width) /
($this->depth ?: 1));
static::$tippingPointCache[$cacheKey] = $tippingPoint;
}
return $tippingPoint;
}
public function isStable()
{
return $this->getTippingPoint() > 0.261;
}
public function jsonSerialize()
{
return [
'item' => $this->item,
'width' => $this->width,
'length' => $this->length,
'depth' => $this->depth,
];
}
public function __toString()
{
return $this->width . '|' . $this->length .
'|' . $this->depth;
}
}
PK�6�[4Y�(�(#boxpacker/OrientatedItemFactory.phpnu�[���<?php
/**
* @package HikaShop for Joomla!
* @version 4.4.1
* @author hikashop.com
* @copyright (C) 2010-2021 HIKARI SOFTWARE. All rights reserved.
* @license GNU/GPLv3 http://www.gnu.org/licenses/gpl-3.0.html
*/
defined('_JEXEC') or die('Restricted access');
?><?php
namespace DVDoug\BoxPacker;
use Psr\Log\LoggerAwareInterface;
use Psr\Log\LoggerAwareTrait;
class OrientatedItemFactory implements LoggerAwareInterface
{
use LoggerAwareTrait;
protected $box;
protected static $emptyBoxCache = [];
public function __construct(Box $box)
{
$this->box = $box;
}
public function getBestOrientation(
Item $item,
OrientatedItem $prevItem = null,
ItemList $nextItems,
$isLastItem,
$widthLeft,
$lengthLeft,
$depthLeft,
$rowLength,
$x,
$y,
$z,
PackedItemList $prevPackedItemList
) {
$possibleOrientations = $this->getPossibleOrientations($item,
$prevItem, $widthLeft, $lengthLeft, $depthLeft, $x, $y, $z,
$prevPackedItemList);
$usableOrientations = $this->getUsableOrientations($item,
$possibleOrientations, $isLastItem);
if (empty($usableOrientations)) {
return null;
}
usort($usableOrientations, function (OrientatedItem $a,
OrientatedItem $b) use ($widthLeft, $lengthLeft, $depthLeft, $nextItems,
$rowLength, $x, $y, $z, $prevPackedItemList) {
$orientationAWidthLeft = $widthLeft - $a->getWidth();
$orientationALengthLeft = $lengthLeft - $a->getLength();
$orientationADepthLeft = $depthLeft - $a->getDepth();
$orientationBWidthLeft = $widthLeft - $b->getWidth();
$orientationBLengthLeft = $lengthLeft - $b->getLength();
$orientationBDepthLeft = $depthLeft - $b->getDepth();
$orientationAMinGap = min($orientationAWidthLeft,
$orientationALengthLeft);
$orientationBMinGap = min($orientationBWidthLeft,
$orientationBLengthLeft);
if ($orientationAMinGap === 0 && ($orientationBMinGap
!== 0 || PHP_MAJOR_VERSION > 5)) { // prefer A if it leaves no gap
return -1;
}
if ($orientationBMinGap === 0) { // prefer B if it leaves no
gap
return 1;
}
if ($nextItems->count()) {
$nextItemFitA =
count($this->getPossibleOrientations($nextItems->top(), $a,
$orientationAWidthLeft, $lengthLeft, $depthLeft, $x, $y, $z,
$prevPackedItemList));
$nextItemFitB =
count($this->getPossibleOrientations($nextItems->top(), $b,
$orientationBWidthLeft, $lengthLeft, $depthLeft, $x, $y, $z,
$prevPackedItemList));
if ($nextItemFitA && !$nextItemFitB) {
return -1;
}
if ($nextItemFitB && !$nextItemFitA) {
return 1;
}
$additionalPackedA =
$this->calculateAdditionalItemsPackedWithThisOrientation($a, $nextItems,
$widthLeft, $lengthLeft, $depthLeft, $rowLength);
$additionalPackedB =
$this->calculateAdditionalItemsPackedWithThisOrientation($b, $nextItems,
$widthLeft, $lengthLeft, $depthLeft, $rowLength);
if ($additionalPackedA > $additionalPackedB) {
return -1;
}
if ($additionalPackedA < $additionalPackedB) {
return 1;
}
if ($additionalPackedA === 0) {
return PHP_MAJOR_VERSION > 5 ? -1 : 1;
}
}
return ($orientationADepthLeft - $orientationBDepthLeft) ?:
($orientationAMinGap - $orientationBMinGap) ?:
($a->getSurfaceFootprint() - $b->getSurfaceFootprint());
});
$bestFit = reset($usableOrientations);
$this->logger->debug('Selected best fit
orientation', ['orientation' => $bestFit]);
return $bestFit;
}
public function getPossibleOrientations(
Item $item,
OrientatedItem $prevItem = null,
$widthLeft,
$lengthLeft,
$depthLeft,
$x,
$y,
$z,
PackedItemList $prevPackedItemList
) {
$orientations = [];
if ($prevItem &&
$this->isSameDimensions($prevItem->getItem(), $item)) {
$orientations[] = new OrientatedItem($item,
$prevItem->getWidth(), $prevItem->getLength(),
$prevItem->getDepth());
} else {
$orientations[] = new OrientatedItem($item,
$item->getWidth(), $item->getLength(), $item->getDepth());
$orientations[] = new OrientatedItem($item,
$item->getLength(), $item->getWidth(), $item->getDepth());
if (!$item->getKeepFlat()) {
$orientations[] = new OrientatedItem($item,
$item->getWidth(), $item->getDepth(), $item->getLength());
$orientations[] = new OrientatedItem($item,
$item->getLength(), $item->getDepth(), $item->getWidth());
$orientations[] = new OrientatedItem($item,
$item->getDepth(), $item->getWidth(), $item->getLength());
$orientations[] = new OrientatedItem($item,
$item->getDepth(), $item->getLength(), $item->getWidth());
}
}
$orientations = array_unique($orientations);
$orientations = array_filter($orientations, function
(OrientatedItem $i) use ($widthLeft, $lengthLeft, $depthLeft) {
return $i->getWidth() <= $widthLeft &&
$i->getLength() <= $lengthLeft && $i->getDepth() <=
$depthLeft;
});
if ($item instanceof ConstrainedPlacementItem) {
$box = $this->box;
$orientations = array_filter($orientations, function
(OrientatedItem $i) use ($box, $x, $y, $z, $prevPackedItemList) {
$constrainedItem = $i->getItem();
return $constrainedItem->canBePacked($box,
$prevPackedItemList, $x, $y, $z, $i->getWidth(), $i->getLength(),
$i->getDepth());
});
}
return $orientations;
}
public function getPossibleOrientationsInEmptyBox(Item $item)
{
$cacheKey = $item->getWidth() .
'|' .
$item->getLength() .
'|' .
$item->getDepth() .
'|' .
($item->getKeepFlat() ? '2D' : '3D') .
'|' .
$this->box->getInnerWidth() .
'|' .
$this->box->getInnerLength() .
'|' .
$this->box->getInnerDepth();
if (isset(static::$emptyBoxCache[$cacheKey])) {
$orientations = static::$emptyBoxCache[$cacheKey];
} else {
$orientations = $this->getPossibleOrientations(
$item,
null,
$this->box->getInnerWidth(),
$this->box->getInnerLength(),
$this->box->getInnerDepth(),
0,
0,
0,
new PackedItemList()
);
static::$emptyBoxCache[$cacheKey] = $orientations;
}
return $orientations;
}
protected function getUsableOrientations(
Item $item,
$possibleOrientations,
$isLastItem
) {
$orientationsToUse = $stableOrientations = $unstableOrientations =
[];
foreach ($possibleOrientations as $orientation) {
if ($orientation->isStable()) {
$stableOrientations[] = $orientation;
} else {
$unstableOrientations[] = $orientation;
}
}
if (count($stableOrientations) > 0) {
$orientationsToUse = $stableOrientations;
} elseif (count($unstableOrientations) > 0) {
$stableOrientationsInEmptyBox =
$this->getStableOrientationsInEmptyBox($item);
if ($isLastItem || count($stableOrientationsInEmptyBox) === 0)
{
$orientationsToUse = $unstableOrientations;
}
}
return $orientationsToUse;
}
protected function getStableOrientationsInEmptyBox(Item $item)
{
$orientationsInEmptyBox =
$this->getPossibleOrientationsInEmptyBox($item);
return array_filter(
$orientationsInEmptyBox,
function (OrientatedItem $orientation) {
return $orientation->isStable();
}
);
}
protected function isSameDimensions(Item $itemA, Item $itemB)
{
$itemADimensions = [$itemA->getWidth(), $itemA->getLength(),
$itemA->getDepth()];
$itemBDimensions = [$itemB->getWidth(), $itemB->getLength(),
$itemB->getDepth()];
sort($itemADimensions);
sort($itemBDimensions);
return $itemADimensions === $itemBDimensions;
}
protected function calculateAdditionalItemsPackedWithThisOrientation(
OrientatedItem $prevItem,
ItemList $nextItems,
$originalWidthLeft,
$originalLengthLeft,
$depthLeft,
$currentRowLengthBeforePacking
) {
$packedCount = 0;
$currentRowLength = max($prevItem->getLength(),
$currentRowLengthBeforePacking);
$itemsToPack = $nextItems->topN(8); // cap lookahead as this
gets recursive and slow
$tempBox = new WorkingVolume($originalWidthLeft -
$prevItem->getWidth(), $currentRowLength, $depthLeft, PHP_INT_MAX);
$tempPacker = new VolumePacker($tempBox, clone $itemsToPack);
$tempPacker->setLookAheadMode(true);
$remainingRowPacked = $tempPacker->pack();
foreach ($remainingRowPacked->getItems() as $packedItem) {
$itemsToPack->remove($packedItem);
}
$tempBox = new WorkingVolume($originalWidthLeft,
$originalLengthLeft - $currentRowLength, $depthLeft, PHP_INT_MAX);
$tempPacker = new VolumePacker($tempBox, clone $itemsToPack);
$tempPacker->setLookAheadMode(true);
$nextRowsPacked = $tempPacker->pack();
foreach ($nextRowsPacked->getItems() as $packedItem) {
$itemsToPack->remove($packedItem);
}
$this->logger->debug('Lookahead with orientation',
['packedCount' => $packedCount, 'orientatedItem'
=> $prevItem]);
return $nextItems->count() - $itemsToPack->count();
}
}
PK�6�[��_P��boxpacker/PackedBox.phpnu�[���<?php
/**
* @package HikaShop for Joomla!
* @version 4.4.1
* @author hikashop.com
* @copyright (C) 2010-2021 HIKARI SOFTWARE. All rights reserved.
* @license GNU/GPLv3 http://www.gnu.org/licenses/gpl-3.0.html
*/
defined('_JEXEC') or die('Restricted access');
?><?php
namespace DVDoug\BoxPacker;
use RuntimeException;
class PackedBox
{
protected $box;
protected $items;
protected $weight;
protected $itemWeight;
protected $remainingWidth;
protected $remainingLength;
protected $remainingDepth;
protected $remainingWeight;
protected $usedWidth;
protected $usedLength;
protected $usedDepth;
protected $packedItemList;
public function getBox()
{
return $this->box;
}
public function getItems()
{
return $this->items;
}
public function getWeight()
{
return $this->box->getEmptyWeight() +
$this->getItemWeight();
}
public function getItemWeight()
{
if (!is_null($this->itemWeight)) {
return $this->itemWeight;
}
$this->itemWeight = 0;
foreach (clone $this->items as $item) {
$this->itemWeight += $item->getWeight();
}
return $this->itemWeight;
}
public function getRemainingWidth()
{
return $this->remainingWidth;
}
public function getRemainingLength()
{
return $this->remainingLength;
}
public function getRemainingDepth()
{
return $this->remainingDepth;
}
public function getUsedWidth()
{
return $this->usedWidth;
}
public function getUsedLength()
{
return $this->usedLength;
}
public function getUsedDepth()
{
return $this->usedDepth;
}
public function getRemainingWeight()
{
return $this->remainingWeight;
}
public function getInnerVolume()
{
return $this->box->getInnerWidth() *
$this->box->getInnerLength() * $this->box->getInnerDepth();
}
public function getUsedVolume()
{
$volume = 0;
foreach (clone $this->items as $item) {
$volume += $item->getVolume();
}
return $volume;
}
public function getUnusedVolume()
{
return $this->getInnerVolume() - $this->getUsedVolume();
}
public function getVolumeUtilisation()
{
$itemVolume = 0;
foreach (clone $this->items as $item) {
$itemVolume += $item->getVolume();
}
return round($itemVolume / $this->box->getInnerVolume() *
100, 1);
}
public function getPackedItems()
{
if (!$this->packedItemList instanceof PackedItemList) {
throw new RuntimeException('No PackedItemList was set. Are
you using the old constructor?');
}
return $this->packedItemList;
}
public function setPackedItems(PackedItemList $packedItemList)
{
$this->packedItemList = $packedItemList;
}
public function __construct(
Box $box,
ItemList $itemList,
$remainingWidth,
$remainingLength,
$remainingDepth,
$remainingWeight,
$usedWidth,
$usedLength,
$usedDepth
) {
$this->box = $box;
$this->items = $itemList;
$this->remainingWidth = $remainingWidth;
$this->remainingLength = $remainingLength;
$this->remainingDepth = $remainingDepth;
$this->remainingWeight = $remainingWeight;
$this->usedWidth = $usedWidth;
$this->usedLength = $usedLength;
$this->usedDepth = $usedDepth;
}
public static function fromPackedItemList(Box $box, PackedItemList
$packedItems)
{
$maxWidth = $maxLength = $maxDepth = $weight = 0;
foreach (clone $packedItems as $item) {
$maxWidth = max($maxWidth, $item->getX() +
$item->getWidth());
$maxLength = max($maxLength, $item->getY() +
$item->getLength());
$maxDepth = max($maxDepth, $item->getZ() +
$item->getDepth());
$weight += $item->getItem()->getWeight();
}
$packedBox = new self(
$box,
$packedItems->asItemList(),
$box->getInnerWidth() - $maxWidth,
$box->getInnerLength() - $maxLength,
$box->getInnerDepth() - $maxDepth,
$box->getMaxWeight() - $box->getEmptyWeight() - $weight,
$maxWidth,
$maxLength,
$maxDepth
);
$packedBox->setPackedItems($packedItems);
return $packedBox;
}
}
PK�6�[!k� � boxpacker/PackedBoxList.phpnu�[���<?php
/**
* @package HikaShop for Joomla!
* @version 4.4.1
* @author hikashop.com
* @copyright (C) 2010-2021 HIKARI SOFTWARE. All rights reserved.
* @license GNU/GPLv3 http://www.gnu.org/licenses/gpl-3.0.html
*/
defined('_JEXEC') or die('Restricted access');
?><?php
namespace DVDoug\BoxPacker;
class PackedBoxList extends \SplMinHeap
{
protected $meanWeight;
public function compare($boxA, $boxB)
{
$choice = $boxA->getItems()->count() -
$boxB->getItems()->count();
if ($choice == 0) {
$choice = $boxA->getVolumeUtilisation() -
$boxB->getVolumeUtilisation();
}
if ($choice == 0) {
$choice = $boxA->getUsedVolume() -
$boxB->getUsedVolume();
}
if ($choice == 0) {
$choice = $boxA->getWeight() - $boxB->getWeight();
}
return $choice;
}
public function reverseCompare($boxA, $boxB)
{
$choice = $boxB->getItems()->count() -
$boxA->getItems()->count();
if ($choice === 0) {
$choice = $boxA->getBox()->getInnerVolume() -
$boxB->getBox()->getInnerVolume();
}
if ($choice === 0) {
$choice = $boxB->getWeight() - $boxA->getWeight();
}
return $choice;
}
public function getMeanWeight()
{
if (!is_null($this->meanWeight)) {
return $this->meanWeight;
}
foreach (clone $this as $box) {
$this->meanWeight += $box->getWeight();
}
return $this->meanWeight /= $this->count();
}
public function getWeightVariance()
{
$mean = $this->getMeanWeight();
$weightVariance = 0;
foreach (clone $this as $box) {
$weightVariance += pow($box->getWeight() - $mean, 2);
}
return round($weightVariance / $this->count(), 1);
}
public function getVolumeUtilisation()
{
$itemVolume = 0;
$boxVolume = 0;
foreach (clone $this as $box) {
$boxVolume += $box->getBox()->getInnerVolume();
foreach (clone $box->getItems() as $item) {
$itemVolume += $item->getVolume();
}
}
return round($itemVolume / $boxVolume * 100, 1);
}
public function insertFromArray(array $boxes)
{
foreach ($boxes as $box) {
$this->insert($box);
}
}
}
PK�6�[
����boxpacker/PackedItem.phpnu�[���<?php
/**
* @package HikaShop for Joomla!
* @version 4.4.1
* @author hikashop.com
* @copyright (C) 2010-2021 HIKARI SOFTWARE. All rights reserved.
* @license GNU/GPLv3 http://www.gnu.org/licenses/gpl-3.0.html
*/
defined('_JEXEC') or die('Restricted access');
?><?php
namespace DVDoug\BoxPacker;
class PackedItem
{
protected $x;
protected $y;
protected $z;
protected $item;
protected $width;
protected $length;
protected $depth;
public function __construct(Item $item, $x, $y, $z, $width, $length,
$depth)
{
$this->item = $item;
$this->x = $x;
$this->y = $y;
$this->z = $z;
$this->width = $width;
$this->length = $length;
$this->depth = $depth;
}
public function getX()
{
return $this->x;
}
public function getY()
{
return $this->y;
}
public function getZ()
{
return $this->z;
}
public function getItem()
{
return $this->item;
}
public function getWidth()
{
return $this->width;
}
public function getLength()
{
return $this->length;
}
public function getDepth()
{
return $this->depth;
}
public function getVolume()
{
return $this->width * $this->length * $this->depth;
}
public static function fromOrientatedItem(OrientatedItem
$orientatedItem, $x, $y, $z)
{
return new static(
$orientatedItem->getItem(),
$x,
$y,
$z,
$orientatedItem->getWidth(),
$orientatedItem->getLength(),
$orientatedItem->getDepth()
);
}
public function toOrientatedItem()
{
return new OrientatedItem($this->item, $this->width,
$this->length, $this->depth);
}
}
PK�6�[�0p�JJboxpacker/PackedItemList.phpnu�[���<?php
/**
* @package HikaShop for Joomla!
* @version 4.4.1
* @author hikashop.com
* @copyright (C) 2010-2021 HIKARI SOFTWARE. All rights reserved.
* @license GNU/GPLv3 http://www.gnu.org/licenses/gpl-3.0.html
*/
defined('_JEXEC') or die('Restricted access');
?><?php
namespace DVDoug\BoxPacker;
class PackedItemList extends \SplMaxHeap
{
public function compare($itemA, $itemB)
{
if ($itemA->getItem()->getVolume() >
$itemB->getItem()->getVolume()) {
return 1;
} elseif ($itemA->getItem()->getVolume() <
$itemB->getItem()->getVolume()) {
return -1;
} else {
return $itemA->getItem()->getWeight() -
$itemB->getItem()->getWeight();
}
}
public function asArray()
{
$return = [];
foreach (clone $this as $item) {
$return[] = $item;
}
return $return;
}
public function asItemArray()
{
$return = [];
foreach (clone $this as $item) {
$return[] = $item->getItem();
}
return $return;
}
public function asItemList()
{
$return = new ItemList();
foreach (clone $this as $packedItem) {
$return->insert($packedItem->getItem());
}
return $return;
}
}
PK�6�[�����boxpacker/PackedLayer.phpnu�[���<?php
/**
* @package HikaShop for Joomla!
* @version 4.4.1
* @author hikashop.com
* @copyright (C) 2010-2021 HIKARI SOFTWARE. All rights reserved.
* @license GNU/GPLv3 http://www.gnu.org/licenses/gpl-3.0.html
*/
defined('_JEXEC') or die('Restricted access');
?><?php
namespace DVDoug\BoxPacker;
class PackedLayer
{
protected $items = [];
public function insert(PackedItem $packedItem)
{
$this->items[] = $packedItem;
}
public function getItems()
{
return $this->items;
}
public function getFootprint()
{
$layerWidth = 0;
$layerLength = 0;
foreach ($this->items as $item) {
$layerWidth = max($layerWidth, $item->getX() +
$item->getWidth());
$layerLength = max($layerLength, $item->getY() +
$item->getLength());
}
return $layerWidth * $layerLength;
}
public function getStartDepth()
{
$startDepth = PHP_INT_MAX;
foreach ($this->items as $item) {
$startDepth = min($startDepth, $item->getZ());
}
return $startDepth;
}
public function getDepth()
{
$layerDepth = 0;
foreach ($this->items as $item) {
$layerDepth = max($layerDepth, $item->getZ() +
$item->getDepth());
}
return $layerDepth - $this->getStartDepth();
}
}
PK�6�[�����boxpacker/Packer.phpnu�[���<?php
/**
* @package HikaShop for Joomla!
* @version 4.4.1
* @author hikashop.com
* @copyright (C) 2010-2021 HIKARI SOFTWARE. All rights reserved.
* @license GNU/GPLv3 http://www.gnu.org/licenses/gpl-3.0.html
*/
defined('_JEXEC') or die('Restricted access');
?><?php
namespace DVDoug\BoxPacker;
use Psr\Log\LoggerAwareInterface;
use Psr\Log\LoggerAwareTrait;
use Psr\Log\LogLevel;
use Psr\Log\NullLogger;
class Packer implements LoggerAwareInterface
{
use LoggerAwareTrait;
protected $maxBoxesToBalanceWeight = 12;
protected $items;
protected $boxes;
public function __construct()
{
$this->items = new ItemList();
$this->boxes = new BoxList();
$this->logger = new NullLogger();
}
public function addItem(Item $item, $qty = 1)
{
for ($i = 0; $i < $qty; ++$i) {
$this->items->insert($item);
}
$this->logger->log(LogLevel::INFO, "added {$qty} x
{$item->getDescription()}", ['item' => $item]);
}
public function setItems($items)
{
if ($items instanceof ItemList) {
$this->items = clone $items;
} else {
$this->items = new ItemList();
foreach ($items as $item) {
$this->items->insert($item);
}
}
}
public function addBox(Box $box)
{
$this->boxes->insert($box);
$this->logger->log(LogLevel::INFO, "added box
{$box->getReference()}", ['box' => $box]);
}
public function setBoxes(BoxList $boxList)
{
$this->boxes = clone $boxList;
}
public function getMaxBoxesToBalanceWeight()
{
return $this->maxBoxesToBalanceWeight;
}
public function setMaxBoxesToBalanceWeight($maxBoxesToBalanceWeight)
{
$this->maxBoxesToBalanceWeight = $maxBoxesToBalanceWeight;
}
public function pack()
{
$packedBoxes = $this->doVolumePacking();
if ($packedBoxes->count() > 1 &&
$packedBoxes->count() <= $this->maxBoxesToBalanceWeight) {
$redistributor = new WeightRedistributor($this->boxes);
$redistributor->setLogger($this->logger);
$packedBoxes =
$redistributor->redistributeWeight($packedBoxes);
}
$this->logger->log(LogLevel::INFO, "[PACKING COMPLETED],
{$packedBoxes->count()} boxes");
return $packedBoxes;
}
public function doVolumePacking()
{
$packedBoxes = new PackedBoxList();
while ($this->items->count()) {
$boxesToEvaluate = clone $this->boxes;
$packedBoxesIteration = new PackedBoxList();
while (!$boxesToEvaluate->isEmpty()) {
$box = $boxesToEvaluate->extract();
$volumePacker = new VolumePacker($box, clone
$this->items);
$volumePacker->setLogger($this->logger);
$packedBox = $volumePacker->pack();
if ($packedBox->getItems()->count()) {
$packedBoxesIteration->insert($packedBox);
if ($packedBox->getItems()->count() ===
$this->items->count()) {
break;
}
}
}
if ($packedBoxesIteration->isEmpty()) {
throw new ItemTooLargeException('Item
'.$this->items->top()->getDescription().' is too large
to fit into any box', $this->items->top());
}
$bestBox = $packedBoxesIteration->top();
$unPackedItems = $this->items->asArray();
foreach (clone $bestBox->getItems() as $packedItem) {
foreach ($unPackedItems as $unpackedKey =>
$unpackedItem) {
if ($packedItem === $unpackedItem) {
unset($unPackedItems[$unpackedKey]);
break;
}
}
}
$unpackedItemList = new ItemList();
foreach ($unPackedItems as $unpackedItem) {
$unpackedItemList->insert($unpackedItem);
}
$this->items = $unpackedItemList;
$packedBoxes->insert($bestBox);
}
return $packedBoxes;
}
}
PK�6�[_��>(>(boxpacker/VolumePacker.phpnu�[���<?php
/**
* @package HikaShop for Joomla!
* @version 4.4.1
* @author hikashop.com
* @copyright (C) 2010-2021 HIKARI SOFTWARE. All rights reserved.
* @license GNU/GPLv3 http://www.gnu.org/licenses/gpl-3.0.html
*/
defined('_JEXEC') or die('Restricted access');
?><?php
namespace DVDoug\BoxPacker;
use Psr\Log\LoggerAwareInterface;
use Psr\Log\LoggerAwareTrait;
use Psr\Log\NullLogger;
class VolumePacker implements LoggerAwareInterface
{
use LoggerAwareTrait;
protected $box;
protected $boxWidth;
protected $boxLength;
protected $items;
protected $skippedItems;
protected $remainingWeight;
protected $boxRotated = false;
protected $layers = [];
protected $lookAheadMode = false;
public function __construct(Box $box, ItemList $items)
{
$this->box = $box;
$this->items = $items;
$this->boxWidth = max($this->box->getInnerWidth(),
$this->box->getInnerLength());
$this->boxLength = min($this->box->getInnerWidth(),
$this->box->getInnerLength());
$this->remainingWeight = $this->box->getMaxWeight() -
$this->box->getEmptyWeight();
$this->skippedItems = new ItemList();
$this->logger = new NullLogger();
if ($this->box->getInnerWidth() !== $this->boxWidth ||
$this->box->getInnerLength() !== $this->boxLength) {
$this->boxRotated = true;
}
}
public function setLookAheadMode($lookAhead)
{
$this->lookAheadMode = $lookAhead;
}
public function pack()
{
$this->logger->debug("[EVALUATING BOX]
{$this->box->getReference()}", ['box' =>
$this->box]);
while (count($this->items) > 0) {
$layerStartDepth = $this->getCurrentPackedDepth();
$this->packLayer($layerStartDepth, $this->boxWidth,
$this->boxLength, $this->box->getInnerDepth() -
$layerStartDepth);
}
if ($this->boxRotated) {
$this->rotateLayersNinetyDegrees();
}
if (!$this->lookAheadMode) {
$this->stabiliseLayers();
}
$this->logger->debug('done with this box');
return PackedBox::fromPackedItemList($this->box,
$this->getPackedItemList());
}
protected function packLayer($startDepth, $widthLeft, $lengthLeft,
$depthLeft)
{
$this->layers[] = $layer = new PackedLayer();
$prevItem = null;
$x = $y = $rowWidth = $rowLength = $layerDepth = 0;
while (count($this->items) > 0) {
$itemToPack = $this->items->extract();
if (!$this->checkConstraints($itemToPack)) {
$this->rebuildItemList();
continue;
}
$orientatedItem = $this->getOrientationForItem($itemToPack,
$prevItem, $this->items, $this->hasItemsLeftToPack(), $widthLeft,
$lengthLeft, $depthLeft, $rowLength, $x, $y, $startDepth);
if ($orientatedItem instanceof OrientatedItem) {
$packedItem =
PackedItem::fromOrientatedItem($orientatedItem, $x, $y, $startDepth);
$layer->insert($packedItem);
$this->remainingWeight -=
$orientatedItem->getItem()->getWeight();
$widthLeft -= $orientatedItem->getWidth();
$rowWidth += $orientatedItem->getWidth();
$rowLength = max($rowLength,
$orientatedItem->getLength());
$layerDepth = max($layerDepth,
$orientatedItem->getDepth());
$stackableDepth = $layerDepth -
$orientatedItem->getDepth();
$this->tryAndStackItemsIntoSpace($layer, $prevItem,
$this->items, $orientatedItem->getWidth(),
$orientatedItem->getLength(), $stackableDepth, $x, $y, $startDepth +
$orientatedItem->getDepth(), $rowLength);
$x += $orientatedItem->getWidth();
$prevItem = $packedItem;
$this->rebuildItemList();
} elseif (count($layer->getItems()) === 0) { // zero items
on layer
$this->logger->debug("doesn't fit on layer
even when empty, skipping for good");
continue;
} elseif ($widthLeft > 0 && count($this->items)
> 0) { // skip for now, move on to the next item
$this->logger->debug("doesn't fit, skipping
for now");
$this->skippedItems->insert($itemToPack);
} elseif ($x > 0 && $lengthLeft >=
min($itemToPack->getWidth(), $itemToPack->getLength(),
$itemToPack->getDepth())) {
$this->logger->debug('No more fit in width wise,
resetting for new row');
$widthLeft += $rowWidth;
$lengthLeft -= $rowLength;
$y += $rowLength;
$x = $rowWidth = $rowLength = 0;
$this->rebuildItemList($itemToPack);
$prevItem = null;
continue;
} else {
$this->logger->debug('no items fit, so starting
next vertical layer');
$this->rebuildItemList($itemToPack);
return;
}
}
}
public function stabiliseLayers()
{
$stabiliser = new LayerStabiliser();
$this->layers = $stabiliser->stabilise($this->layers);
}
protected function getOrientationForItem(
Item $itemToPack,
PackedItem $prevItem = null,
ItemList $nextItems,
$isLastItem,
$maxWidth,
$maxLength,
$maxDepth,
$rowLength,
$x,
$y,
$z
) {
$this->logger->debug(
"evaluating item {$itemToPack->getDescription()} for
fit",
[
'item' => $itemToPack,
'space' => [
'maxWidth' => $maxWidth,
'maxLength' => $maxLength,
'maxDepth' => $maxDepth,
],
]
);
$prevOrientatedItem = $prevItem ? $prevItem->toOrientatedItem()
: null;
$prevPackedItemList = $itemToPack instanceof
ConstrainedPlacementItem ? $this->getPackedItemList() : new
PackedItemList(); // don't calculate it if not going to be used
$orientatedItemFactory = new OrientatedItemFactory($this->box);
$orientatedItemFactory->setLogger($this->logger);
$orientatedItemDecision =
$orientatedItemFactory->getBestOrientation($itemToPack,
$prevOrientatedItem, $nextItems, $isLastItem, $maxWidth, $maxLength,
$maxDepth, $rowLength, $x, $y, $z, $prevPackedItemList);
return $orientatedItemDecision;
}
protected function tryAndStackItemsIntoSpace(
PackedLayer $layer,
PackedItem $prevItem = null,
ItemList $nextItems,
$maxWidth,
$maxLength,
$maxDepth,
$x,
$y,
$z,
$rowLength
) {
while (count($this->items) > 0 &&
$this->checkNonDimensionalConstraints($this->items->top())) {
$stackedItem = $this->getOrientationForItem(
$this->items->top(),
$prevItem,
$nextItems,
$this->items->count() === 1,
$maxWidth,
$maxLength,
$maxDepth,
$rowLength,
$x,
$y,
$z
);
if ($stackedItem) {
$this->remainingWeight -=
$this->items->top()->getWeight();
$layer->insert(PackedItem::fromOrientatedItem($stackedItem, $x, $y,
$z));
$this->items->extract();
$maxDepth -= $stackedItem->getDepth();
$z += $stackedItem->getDepth();
} else {
break;
}
}
}
protected function checkConstraints(
Item $itemToPack
) {
return $this->checkNonDimensionalConstraints($itemToPack)
&&
$this->checkDimensionalConstraints($itemToPack);
}
protected function checkNonDimensionalConstraints(Item $itemToPack)
{
$weightOK = $itemToPack->getWeight() <=
$this->remainingWeight;
if ($itemToPack instanceof ConstrainedItem) {
return $weightOK &&
$itemToPack->canBePackedInBox($this->getPackedItemList()->asItemList(),
$this->box);
}
return $weightOK;
}
protected function checkDimensionalConstraints(Item $itemToPack)
{
$orientatedItemFactory = new OrientatedItemFactory($this->box);
$orientatedItemFactory->setLogger($this->logger);
return (bool)
$orientatedItemFactory->getPossibleOrientationsInEmptyBox($itemToPack);
}
protected function rebuildItemList(Item $currentItem = null)
{
if (count($this->items) === 0) {
$this->items = $this->skippedItems;
$this->skippedItems = new ItemList();
}
if ($currentItem instanceof Item) {
$this->items->insert($currentItem);
}
}
protected function rotateLayersNinetyDegrees()
{
foreach ($this->layers as $i => $originalLayer) {
$newLayer = new PackedLayer();
foreach ($originalLayer->getItems() as $item) {
$packedItem = new PackedItem($item->getItem(),
$item->getY(), $item->getX(), $item->getZ(),
$item->getLength(), $item->getWidth(), $item->getDepth());
$newLayer->insert($packedItem);
}
$this->layers[$i] = $newLayer;
}
}
protected function hasItemsLeftToPack()
{
return count($this->skippedItems) + count($this->items) ===
0;
}
protected function getPackedItemList()
{
$packedItemList = new PackedItemList();
foreach ($this->layers as $layer) {
foreach ($layer->getItems() as $packedItem) {
$packedItemList->insert($packedItem);
}
}
return $packedItemList;
}
protected function getCurrentPackedDepth()
{
$depth = 0;
foreach ($this->layers as $layer) {
$depth += $layer->getDepth();
}
return $depth;
}
}
PK�6�[Q�,���!boxpacker/WeightRedistributor.phpnu�[���<?php
/**
* @package HikaShop for Joomla!
* @version 4.4.1
* @author hikashop.com
* @copyright (C) 2010-2021 HIKARI SOFTWARE. All rights reserved.
* @license GNU/GPLv3 http://www.gnu.org/licenses/gpl-3.0.html
*/
defined('_JEXEC') or die('Restricted access');
?><?php
namespace DVDoug\BoxPacker;
use Psr\Log\LoggerAwareInterface;
use Psr\Log\LoggerAwareTrait;
use Psr\Log\LogLevel;
use Psr\Log\NullLogger;
class WeightRedistributor implements LoggerAwareInterface
{
use LoggerAwareTrait;
private $boxes;
public function __construct(BoxList $boxList)
{
$this->boxes = clone $boxList;
$this->logger = new NullLogger();
}
public function redistributeWeight(PackedBoxList $originalBoxes)
{
$targetWeight = $originalBoxes->getMeanWeight();
$this->logger->log(LogLevel::DEBUG, "repacking for
weight distribution, weight variance
{$originalBoxes->getWeightVariance()}, target weight
{$targetWeight}");
$boxes = iterator_to_array($originalBoxes);
usort($boxes, function (PackedBox $boxA, PackedBox $boxB) {
return $boxB->getWeight() - $boxA->getWeight();
});
do {
$iterationSuccessful = false;
foreach ($boxes as $a => &$boxA) {
foreach ($boxes as $b => &$boxB) {
if ($b <= $a || $boxA->getWeight() ===
$boxB->getWeight()) {
continue; //no need to evaluate
}
$iterationSuccessful = $this->equaliseWeight($boxA,
$boxB, $targetWeight);
if ($iterationSuccessful) {
$boxes = array_filter($boxes, function ($box) {
//remove any now-empty boxes from the list
return $box instanceof PackedBox;
});
break 2;
}
}
}
} while ($iterationSuccessful);
$packedBoxes = new PackedBoxList();
$packedBoxes->insertFromArray($boxes);
return $packedBoxes;
}
private function equaliseWeight(PackedBox &$boxA, PackedBox
&$boxB, $targetWeight)
{
$anyIterationSuccessful = false;
if ($boxA->getWeight() > $boxB->getWeight()) {
$overWeightBox = $boxA;
$underWeightBox = $boxB;
} else {
$overWeightBox = $boxB;
$underWeightBox = $boxA;
}
$overWeightBoxItems = $overWeightBox->getItems()->asArray();
$underWeightBoxItems =
$underWeightBox->getItems()->asArray();
foreach ($overWeightBoxItems as $key => $overWeightItem) {
if ($overWeightItem->getWeight() + $boxB->getWeight()
> $targetWeight) {
continue; // moving this item would harm more than help
}
$newLighterBoxes =
$this->doVolumeRepack(array_merge($underWeightBoxItems,
[$overWeightItem]));
if (count($newLighterBoxes) !== 1) {
continue; //only want to move this item if it still fits in
a single box
}
$underWeightBoxItems[] = $overWeightItem;
if (count($overWeightBoxItems) === 1) { //sometimes a repack
can be efficient enough to eliminate a box
$boxB = $newLighterBoxes->top();
$boxA = null;
return true;
} else {
unset($overWeightBoxItems[$key]);
$newHeavierBoxes =
$this->doVolumeRepack($overWeightBoxItems);
if (count($newHeavierBoxes) !== 1) {
continue;
}
if ($this->didRepackActuallyHelp($boxA, $boxB,
$newHeavierBoxes->top(), $newLighterBoxes->top())) {
$boxB = $newLighterBoxes->top();
$boxA = $newHeavierBoxes->top();
$anyIterationSuccessful = true;
}
}
}
return $anyIterationSuccessful;
}
private function doVolumeRepack($items)
{
$packer = new Packer();
$packer->setBoxes($this->boxes); // use the full set of boxes
to allow smaller/larger for full efficiency
$packer->setItems($items);
return $packer->doVolumePacking();
}
private function didRepackActuallyHelp(PackedBox $oldBoxA, PackedBox
$oldBoxB, PackedBox $newBoxA, PackedBox $newBoxB)
{
$oldList = new PackedBoxList();
$oldList->insertFromArray([$oldBoxA, $oldBoxB]);
$newList = new PackedBoxList();
$newList->insertFromArray([$newBoxA, $newBoxB]);
return $newList->getWeightVariance() <
$oldList->getWeightVariance();
}
}
PK�6�[Y�>
zzboxpacker/WorkingVolume.phpnu�[���<?php
/**
* @package HikaShop for Joomla!
* @version 4.4.1
* @author hikashop.com
* @copyright (C) 2010-2021 HIKARI SOFTWARE. All rights reserved.
* @license GNU/GPLv3 http://www.gnu.org/licenses/gpl-3.0.html
*/
defined('_JEXEC') or die('Restricted access');
?><?php
namespace DVDoug\BoxPacker;
use JsonSerializable;
class WorkingVolume implements Box, JsonSerializable
{
private $width;
private $length;
private $depth;
private $maxWeight;
public function __construct(
$width,
$length,
$depth,
$maxWeight
) {
$this->width = $width;
$this->length = $length;
$this->depth = $depth;
$this->maxWeight = $maxWeight;
}
public function getReference()
{
return 'Working Volume';
}
public function getOuterWidth()
{
return $this->width;
}
public function getOuterLength()
{
return $this->length;
}
public function getOuterDepth()
{
return $this->depth;
}
public function getEmptyWeight()
{
return 0;
}
public function getInnerWidth()
{
return $this->width;
}
public function getInnerLength()
{
return $this->length;
}
public function getInnerDepth()
{
return $this->depth;
}
public function getMaxWeight()
{
return $this->maxWeight;
}
public function getInnerVolume()
{
return $this->width * $this->length * $this->depth;
}
public function jsonSerialize()
{
return [
'reference' => $this->getReference(),
'width' => $this->width,
'length' => $this->length,
'depth' => $this->depth,
'maxWeight' => $this->maxWeight,
];
}
}
PK�6�[�
YO@@
boxpacker.phpnu�[���<?php
/**
* @package HikaShop for Joomla!
* @version 4.4.1
* @author hikashop.com
* @copyright (C) 2010-2021 HIKARI SOFTWARE. All rights reserved.
* @license GNU/GPLv3 http://www.gnu.org/licenses/gpl-3.0.html
*/
defined('_JEXEC') or die('Restricted access');
?><?php
class hikashopBoxpackerInc {
}
PK�6�["h�bss
compat.phpnu�[���<?php
/**
* @package HikaShop for Joomla!
* @version 4.4.1
* @author hikashop.com
* @copyright (C) 2010-2021 HIKARI SOFTWARE. All rights reserved.
* @license GNU/GPLv3 http://www.gnu.org/licenses/gpl-3.0.html
*/
defined('_JEXEC') or die('Restricted access');
?><?php
function bccomp($num1, $num2, $scale = 0) {
if(!preg_match("/^\+?(\d+)(\.\d+)?$/", $num1, $tmp1) ||
!preg_match("/^\+?(\d+)(\.\d+)?$/", $num2, $tmp2))
return 0;
$num1 = ltrim($tmp1[1], '0');
$num2 = ltrim($tmp2[1], '0');
if(strlen($num1) > strlen($num2))
return 1;
if(strlen($num1) < strlen($num2))
return -1;
$dec1 = isset($tmp1[2]) ? rtrim(substr($tmp1[2], 1), '0') :
'';
$dec2 = isset($tmp2[2]) ? rtrim(substr($tmp2[2], 1), '0') :
'';
if($scale != null) {
$dec1 = substr($dec1, 0, $scale);
$dec2 = substr($dec2, 0, $scale);
}
$DLen = max(strlen($dec1), strlen($dec2));
$num1 .= str_pad($dec1, $DLen, '0');
$num2 .= str_pad($dec2, $DLen, '0');
for($i = 0; $i < strlen($num1); $i++) {
if((int)$num1[$i] > (int)$num2[$i])
return 1;
if((int)$num1[$i] < (int)$num2[$i])
return -1;
}
return 0;
}
PK�6�[P��M!T!Texpression.phpnu�[���<?php
/**
* @package HikaShop for Joomla!
* @version 4.4.1
* @author hikashop.com
* @copyright (C) 2010-2021 HIKARI SOFTWARE. All rights reserved.
* @license GNU/GPLv3 http://www.gnu.org/licenses/gpl-3.0.html
*/
defined('_JEXEC') or die('Restricted access');
?><?php
class HikashopExpressionInc {
var $suppress_errors = false;
var $last_error = null;
var $v = array('e'=>2.71,'pi'=>3.14); //
variables (and constants)
var $f = array(); // user-defined functions
var $vb = array('e', 'pi'); // constants
var $fb = array( // built-in functions
'sin','sinh','arcsin','asin','arcsinh','asinh',
'cos','cosh','arccos','acos','arccosh','acosh',
'tan','tanh','arctan','atan','arctanh','atanh',
'sqrt','abs','ln','log',
'ceil', 'intval', 'floor', 'round',
'exp');
var $functions = array(); // function defined outside of Expression as
closures
function __construct() {
$this->v['pi'] = pi();
$this->v['e'] = exp(1);
}
function e($expr) {
return $this->evaluate($expr);
}
function evaluate($expr) {
$this->last_error = null;
$expr = trim($expr);
if (substr($expr, -1, 1) == ';') $expr = substr($expr, 0,
strlen($expr)-1); // strip semicolons at the end
if (preg_match('/^\s*([a-z]\w*)\s*=(?!~|=)\s*(.+)$/',
$expr, $matches)) {
if (in_array($matches[1], $this->vb)) { // make sure
we're not assigning to a constant
return $this->trigger("cannot assign to constant
'$matches[1]'");
}
$tmp = $this->pfx($this->nfx($matches[2]));
$this->v[$matches[1]] = $tmp; // if so, stick it in the
variable array
return $this->v[$matches[1]]; // and return the resulting
value
} elseif
(preg_match('/^\s*([a-z]\w*)\s*\((?:\s*([a-z]\w*(?:\s*,\s*[a-z]\w*)*)\s*)?\)\s*=(?!~|=)\s*(.+)$/',
$expr, $matches)) {
$fnn = $matches[1]; // get the function name
if (in_array($matches[1], $this->fb)) { // make sure it
isn't built in
return $this->trigger("cannot redefine built-in
function '$matches[1]()'");
}
if ($matches[2] != "") {
$args = explode(",",
preg_replace("/\s+/", "", $matches[2])); // get the
arguments
} else {
$args = array();
}
if (($stack = $this->nfx($matches[3])) === false) return
false; // see if it can be converted to postfix
for ($i = 0; $i<count($stack); $i++) { // freeze the state
of the non-argument variables
$token = $stack[$i];
if (preg_match('/^[a-z]\w*$/', $token) and
!in_array($token, $args)) {
if (array_key_exists($token, $this->v)) {
$stack[$i] = $this->v[$token];
} else {
return $this->trigger("undefined variable
'$token' in function definition");
}
}
}
$this->f[$fnn] = array('args'=>$args,
'func'=>$stack);
return true;
} else {
return $this->pfx($this->nfx($expr)); // straight up
evaluation, woo
}
}
function vars() {
$output = $this->v;
unset($output['pi']);
unset($output['e']);
return $output;
}
function funcs() {
$output = array();
foreach ($this->f as $fnn=>$dat)
$output[] = $fnn . '(' . implode(',',
$dat['args']) . ')';
return $output;
}
function nfx($expr) {
$index = 0;
$stack = new HikashopExpressionStack;
$output = array(); // postfix form of expression, to be passed to
pfx()
$expr = trim($expr);
$ops = array('+', '-', '*',
'/', '^', '_', '%',
'>', '<', '>=', '<=',
'==', '!=', '=~', '&&',
'||', '!');
$ops_r =
array('+'=>0,'-'=>0,'*'=>0,'/'=>0,'%'=>0,'^'=>1,'>'=>0,
'<'=>0,'>='=>0,'<='=>0,'=='=>0,'!='=>0,'=~'=>0,
'&&'=>0,'||'=>0,'!'=>0); //
right-associative operator?
$ops_p =
array('+'=>3,'-'=>3,'*'=>4,'/'=>4,'_'=>4,'%'=>4,'^'=>5,'>'=>2,'<'=>2,
'>='=>2,'<='=>2,'=='=>2,'!='=>2,'=~'=>2,'&&'=>1,'||'=>1,'!'=>5);
// operator precedence
$expecting_op = false; // we use this in syntax-checking the
expression
$first_argument = false;
$i = 0;
$matcher = false;
while(1) { // 1 Infinite Loop ;)
$op = substr(substr($expr, $index), 0, 2); // get the first two
characters at the current index
if
(preg_match("/^[+\-*\/^_\"<>=%(){\[!~,](?!=|~)/", $op)
|| preg_match("/\w/", $op)) {
$op = substr($expr, $index, 1);
}
$single_str =
'(?<!\\\\)"(?:(?:(?<!\\\\)(?:\\\\{2})*\\\\)"|[^"])*(?<![^\\\\]\\\\)"';
$double_str =
"(?<!\\\\)'(?:(?:(?<!\\\\)(?:\\\\{2})*\\\\)'|[^'])*(?<![^\\\\]\\\\)'";
$regex =
"(?<!\\\\)\/(?:[^\/]|\\\\\/)+\/[imsxUXJ]*";
$json =
'[\[{](?>"(?:[^"]|\\\\")*"|[^[{\]}]|(?1))*[\]}]';
$number = '[\d.]+e\d+|\d+(?:\.\d*)?|\.\d+';
$name = '[a-z]\w*\(?|\\$\w+';
$parenthesis = '\\(';
$ex =
preg_match("%^($single_str|$double_str|$json|$name|$regex|$number|$parenthesis)%",
substr($expr, $index), $match);
if ($op == '[' && $expecting_op &&
$ex) {
if (!preg_match("/^\[(.*)\]$/", $match[1],
$matches)) {
return $this->trigger("invalid array
access");
}
$stack->push('[');
$stack->push($matches[1]);
$index += strlen($match[1]);
} elseif ($op == '-' and !$expecting_op) { // is it a
negation instead of a minus?
$stack->push('_'); // put a negation on the
stack
$index++;
} elseif ($op == '_') { // we have to explicitly deny
this, because it's legal on the stack
return $this->trigger("illegal character
'_'"); // but not in the input expression
} elseif ($ex && $matcher &&
preg_match("%^" . $regex . "$%", $match[1])) {
$stack->push('"' . $match[1] .
'"');
$index += strlen($match[1]);
$op = null;
$expecting_op = false;
$matcher = false;
break;
} elseif (((in_array($op, $ops) or $ex) and $expecting_op) or
in_array($op, $ops) and !$expecting_op or
(!$matcher && $ex &&
preg_match("%^" . $regex . "$%", $match[1]))) {
while($stack->count > 0 and ($o2 = $stack->last())
and in_array($o2, $ops) and ($ops_r[$op] ? $ops_p[$op] < $ops_p[$o2] :
$ops_p[$op] <= $ops_p[$o2])) {
$output[] = $stack->pop(); // pop stuff off the
stack into the output
}
$stack->push($op); // finally put OUR operator onto the
stack
$index += strlen($op);
$expecting_op = false;
$matcher = $op == '=~';
} elseif ($op == ')' and $expecting_op || !$ex) { //
ready to close a parenthesis?
while (($o2 = $stack->pop()) != '(') { // pop
off the stack back to the last (
if (is_null($o2)) return
$this->trigger("unexpected ')'");
else $output[] = $o2;
}
if (preg_match("/^([a-z]\w*)\($/",
$stack->last(2), $matches)) { // did we just close a function?
$fnn = $matches[1]; // get the function name
$arg_count = $stack->pop(); // see how many
arguments there were (cleverly stored on the stack, thank you)
$output[] = $stack->pop(); // pop the function and
push onto the output
if (in_array($fnn, $this->fb)) { // check the
argument count
if($arg_count > 1)
return $this->trigger("too many
arguments ($arg_count given, 1 expected)");
} elseif (array_key_exists($fnn, $this->f)) {
if ($arg_count !=
count($this->f[$fnn]['args']))
return $this->trigger("wrong number of
arguments ($arg_count given, " .
count($this->f[$fnn]['args']) . " expected) " .
json_encode($this->f[$fnn]['args']));
} elseif (array_key_exists($fnn, $this->functions))
{
$func_reflection = new
ReflectionFunction($this->functions[$fnn]);
$count =
$func_reflection->getNumberOfParameters();
if ($arg_count != $count)
return $this->trigger("wrong number of
arguments ($arg_count given, " . $count . " expected)");
} else { // did we somehow push a non-function on the
stack? this should never happen
return $this->trigger("internal
error");
}
}
$index++;
} elseif ($op == ',' and $expecting_op) { // did we
just finish a function argument?
while (($o2 = $stack->pop()) != '(') {
if (is_null($o2)) return
$this->trigger("unexpected ','"); // oops, never had
a (
else $output[] = $o2; // pop the argument expression
stuff and push onto the output
}
if (!preg_match("/^([a-z]\w*)\($/",
$stack->last(2), $matches))
return $this->trigger("unexpected
','");
if ($first_argument) {
$first_argument = false;
} else {
$stack->push($stack->pop()+1); // increment the
argument count
}
$stack->push('('); // put the ( back on,
we'll need to pop back to it again
$index++;
$expecting_op = false;
} elseif ($op == '(' and !$expecting_op) {
$stack->push('('); // that was easy
$index++;
$allow_neg = true;
} elseif ($ex and !$expecting_op) { // do we now have a
function/variable/number?
$expecting_op = true;
$val = $match[1];
if ($op == '[' || $op == "{" ||
preg_match("/null|true|false/", $match[1])) {
$output[] = $val;
} elseif (preg_match("/^([a-z]\w*)\($/", $val,
$matches)) { // may be func, or variable w/ implicit multiplication against
parentheses...
if (in_array($matches[1], $this->fb) or
array_key_exists($matches[1], $this->f) or
array_key_exists($matches[1], $this->functions))
{ // it's a func
$stack->push($val);
$stack->push(0);
$stack->push('(');
$expecting_op = false;
} else { // it's a var w/ implicit multiplication
$val = $matches[1];
$output[] = $val;
}
} else { // it's a plain old var or num
$output[] = $val;
if (preg_match("/^([a-z]\w*)\($/",
$stack->last(3))) {
$first_argument = true;
while (($o2 = $stack->pop()) != '(')
{
if (is_null($o2)) return
$this->trigger("unexpected error"); // oops, never had a (
else $output[] = $o2; // pop the argument
expression stuff and push onto the output
}
if (!preg_match("/^([a-z]\w*)\($/",
$stack->last(2), $matches))
return $this->trigger("unexpected
error");
$stack->push($stack->pop()+1); // increment
the argument count
$stack->push('('); // put the ( back
on, we'll need to pop back to it again
}
}
$index += strlen($val);
} elseif ($op == ')') { // miscellaneous error
checking
return $this->trigger("unexpected
')'");
} elseif (in_array($op, $ops) and !$expecting_op) {
return $this->trigger("unexpected operator
'$op'");
} else { // I don't even want to know what you did to get
here
return $this->trigger("an unexpected error occured
" . json_encode($op) . " " . json_encode($match) . "
". ($ex?'true':'false') . " " . $expr);
}
if ($index == strlen($expr)) {
if (in_array($op, $ops)) { // did we end with an operator?
bad.
return $this->trigger("operator '$op'
lacks operand");
} else {
break;
}
}
while (substr($expr, $index, 1) == ' ') { // step the
index past whitespace (pretty much turns whitespace
$index++; // into implicit
multiplication if no operator is there)
}
}
while (!is_null($op = $stack->pop())) { // pop everything off
the stack and push onto output
if ($op == '(') return
$this->trigger("expecting ')'"); // if there are (s
on the stack, ()s were unbalanced
$output[] = $op;
}
return $output;
}
function pfx($tokens, $vars = array()) {
if ($tokens == false) return false;
$stack = new HikashopExpressionStack();
foreach ($tokens as $token) { // nice and easy
if (in_array($token, array('+', '-',
'*', '/', '^', '<',
'>', '<=', '>=', '==',
'&&', '||', '!=', '=~',
'%'))) {
$op2 = $stack->pop();
$op1 = $stack->pop();
switch ($token) {
case '+':
if (is_string($op1) || is_string($op2)) {
$stack->push((string)$op1 . (string)$op2);
} else {
$stack->push($op1 + $op2);
}
break;
case '-':
$stack->push($op1 - $op2); break;
case '*':
$stack->push($op1 * $op2); break;
case '/':
if ($op2 == 0) return
$this->trigger("division by zero");
$stack->push($op1 / $op2); break;
case '%':
$stack->push($op1 % $op2); break;
case '^':
$stack->push(pow($op1, $op2)); break;
case '>':
$stack->push($op1 > $op2); break;
case '<':
$stack->push($op1 < $op2); break;
case '>=':
$stack->push($op1 >= $op2); break;
case '<=':
$stack->push($op1 <= $op2); break;
case '==':
if (is_array($op1) && is_array($op2)) {
$stack->push(json_encode($op1) ==
json_encode($op2));
} else {
$stack->push($op1 == $op2);
}
break;
case '!=':
if (is_array($op1) && is_array($op2)) {
$stack->push(json_encode($op1) !=
json_encode($op2));
} else {
$stack->push($op1 != $op2);
}
break;
case '=~':
$value = @preg_match($op2, $op1, $match);
if (!is_int($value)) {
return $this->trigger("Invalid regex
" . json_encode($op2));
}
$stack->push($value);
for ($i = 0; $i < count($match); $i++) {
$this->v['$' . $i] = $match[$i];
}
break;
case '&&':
$stack->push($op1 ? $op2 : $op1); break;
case '||':
$stack->push($op1 ? $op1 : $op2); break;
}
} elseif ($token == '!') {
$stack->push(!$stack->pop());
} elseif ($token == '[') {
$selector = $stack->pop();
$object = $stack->pop();
if (is_object($object)) {
$stack->push($object->$selector);
} elseif (is_array($object)) {
$stack->push($object[$selector]);
} else {
return $this->trigger("invalid object for
selector");
}
} elseif ($token == "_") {
$stack->push(-1*$stack->pop());
} elseif (preg_match("/^([a-z]\w*)\($/", $token,
$matches)) { // it's a function!
$fnn = $matches[1];
if (in_array($fnn, $this->fb)) { // built-in function:
if (is_null($op1 = $stack->pop())) return
$this->trigger("internal error");
$fnn = preg_replace("/^arc/", "a",
$fnn); // for the 'arc' trig synonyms
if ($fnn == 'ln') $fnn = 'log';
$stack->push($fnn($op1)); // perfectly safe variable
function call
} elseif (array_key_exists($fnn, $this->f)) { // user
function
$args = array();
for ($i = count($this->f[$fnn]['args'])-1;
$i >= 0; $i--) {
if ($stack->empty()) {
return $this->trigger("internal error
" . $fnn . " " .
json_encode($this->f[$fnn]['args']));
}
$args[$this->f[$fnn]['args'][$i]] =
$stack->pop();
}
$stack->push($this->pfx($this->f[$fnn]['func'], $args));
// yay... recursion!!!!
} else if (array_key_exists($fnn, $this->functions)) {
$reflection = new
ReflectionFunction($this->functions[$fnn]);
$count = $reflection->getNumberOfParameters();
for ($i = $count-1; $i >= 0; $i--) {
if ($stack->empty()) {
return $this->trigger("internal
error");
}
$args[] = $stack->pop();
}
$stack->push($reflection->invokeArgs($args));
}
} else {
if
(preg_match('/^([\[{](?>"(?:[^"]|\\")*"|[^[{\]}]|(?1))*[\]}])$/',
$token) ||
preg_match("/^(null|true|false)$/", $token))
{ // json
if ($token == 'null') {
$value = null;
} elseif ($token == 'true') {
$value = true;
} elseif ($token == 'false') {
$value = false;
} else {
$value = json_decode($token);
if ($value == null) {
return $this->trigger("invalid json
" . $token);
}
}
$stack->push($value);
} elseif (is_numeric($token)) {
$stack->push(0+$token);
} else if
(preg_match("/^['\\\"](.*)['\\\"]$/",
$token)) {
$stack->push(json_decode(preg_replace_callback("/^['\\\"](.*)['\\\"]$/",
function($matches) {
$m = array("/\\\\'/",
'/(?<!\\\\)"/');
$r = array("'",
'\\"');
return '"' . preg_replace($m, $r,
$matches[1]) . '"';
}, $token)));
} elseif (array_key_exists($token, $this->v)) {
$stack->push($this->v[$token]);
} elseif (array_key_exists($token, $vars)) {
$stack->push($vars[$token]);
} else {
return $this->trigger("undefined variable
'$token'");
}
}
}
if ($stack->count != 1) return $this->trigger("internal
error");
return $stack->pop();
}
function trigger($msg) {
$this->last_error = $msg;
if (!$this->suppress_errors) trigger_error($msg,
E_USER_WARNING);
return false;
}
}
class HikashopExpressionStack {
var $stack = array();
var $count = 0;
function push($val) {
$this->stack[$this->count] = $val;
$this->count++;
}
function pop() {
if ($this->count > 0) {
$this->count--;
return $this->stack[$this->count];
}
return null;
}
function empty() {
return empty($this->stack);
}
function last($n=1) {
if (isset($this->stack[$this->count-$n])) {
return $this->stack[$this->count-$n];
}
return;
}
}
PK�6�[��~ة
�
geolocation.phpnu�[���<?php
/**
* @package HikaShop for Joomla!
* @version 2.2.3
* @author hikashop.com
* @copyright (C) 2010-2013 HIKARI SOFTWARE. All rights reserved.
* @license GNU/GPLv3 http://www.gnu.org/licenses/gpl-3.0.html
*/
defined('_JEXEC') or die('Restricted access');
?><?php
class hikashopGeolocationInc{
var $errors = array();
var $service = 'api.ipinfodb.com';
var $version = 'v3';
var $apiKey = '';
var $timeout = 10;
function setKey($key){
if(!empty($key)) $this->apiKey = $key;
}
function setTimeout($key){
if(!empty($key)) $this->timeout = $key;
}
function getError(){
return implode("\n", $this->errors);
}
function getCountry($host){
return $this->getResult($host, 'ip-country');
}
function getCity($host){
return $this->getResult($host, 'ip-city');
}
function getResult($host, $name){
$ip = @gethostbyname($host);
if(preg_match('/^(?:25[0-5]|2[0-4]\d|1\d\d|[1-9]\d|\d)(?:[.](?:25[0-5]|2[0-4]\d|1\d\d|[1-9]\d|\d)){3}$/',
$ip)){
return $this->curlRequest($ip);
}
$this->errors[] = '"' . $host . '" is not a
valid IP address or hostname.';
return;
}
function curlRequest($ip) {
$qs = 'http://' . $this->service . '/' .
$this->version . '/ip-country/' . '?ip=' . $ip .
'&format=json&key=' . $this->apiKey;
$app =& JFactory::getApplication();
if(!function_exists('curl_init')){
$app->enqueueMessage('The HikaShop Geolocation plugin needs the
CURL library installed but it seems that it is not available on your
server. Please contact your web hosting to set it
up.','error');
return false;
}
if(!function_exists('json_decode')){
$app->enqueueMessage('The HikaShop Geolocation plugin can only
work with PHP 5.2 at least. Please ask your web hosting to update your PHP
version','error');
return false;
}
if (!isset($this->curl)) {
$this->curl = curl_init();
curl_setopt ($this->curl, CURLOPT_FAILONERROR, TRUE);
if (@ini_get('open_basedir') == '' &&
@ini_get('safe_mode' == 'Off')) {
curl_setopt ($this->curl, CURLOPT_FOLLOWLOCATION, TRUE);
}
curl_setopt ($this->curl, CURLOPT_RETURNTRANSFER, TRUE);
curl_setopt ($this->curl, CURLOPT_CONNECTTIMEOUT,
$this->timeout);
curl_setopt ($this->curl, CURLOPT_TIMEOUT, $this->timeout);
}
curl_setopt ($this->curl, CURLOPT_URL, $qs);
$json = curl_exec($this->curl);
if(curl_errno($this->curl) || $json === FALSE) {
$err = curl_error($this->curl);
$app->enqueueMessage('cURL failed. Error: ' . $err);
}
$response = json_decode($json);
if ($response->statusCode != 'OK') {
$app->enqueueMessage('API returned error: ' .
$response->statusMessage);
}
return $response;
}
}
PK�6�[B�DW��
geoplugin.phpnu�[���<?php
/**
* @package HikaShop for Joomla!
* @version 4.4.1
* @author hikashop.com
* @copyright (C) 2010-2021 HIKARI SOFTWARE. All rights reserved.
* @license GNU/GPLv3 http://www.gnu.org/licenses/gpl-3.0.html
*/
defined('_JEXEC') or die('Restricted access');
?><?php
class HikashopGeopluginInc {
var $host =
'http://www.geoplugin.net/php.gp?ip={IP}&base_currency={CURRENCY}';
var $currency = 'USD';
var $ip = null;
var $city = null;
var $regionName = null;
var $areaCode = null;
var $dmaCode = null;
var $countryCode = null;
var $countryName = null;
var $continentCode = null;
var $latitude = null;
var $longitude = null;
var $currencyCode = null;
var $currencySymbol = null;
var $currencyConverter = null;
var $timeout= 10;
function geoPlugin() {
}
function locate($ip = null) {
global $_SERVER;
if ( is_null( $ip ) ) {
$ip = $_SERVER['REMOTE_ADDR'];
}
$host = str_replace( '{IP}', $ip, $this->host );
$host = str_replace( '{CURRENCY}', $this->currency, $host
);
$data = array();
$response = $this->fetch($host);
if(preg_match('#O:[0-9]+:#',$response)){
return false;
}
$data = hikashop_unserialize($response);
$this->ip = $ip;
$this->city = $data['geoplugin_city'];
$this->regionName = $data['geoplugin_region'];
$this->areaCode = $data['geoplugin_areaCode'];
$this->dmaCode = $data['geoplugin_dmaCode'];
$this->countryCode = $data['geoplugin_countryCode'];
$this->countryName = $data['geoplugin_countryName'];
$this->continentCode = $data['geoplugin_continentCode'];
$this->latitude = $data['geoplugin_latitude'];
$this->longitude = $data['geoplugin_longitude'];
$this->currencyCode = $data['geoplugin_currencyCode'];
$this->currencySymbol = $data['geoplugin_currencySymbol'];
$this->currencyConverter =
$data['geoplugin_currencyConverter'];
}
function fetch($host) {
if ( function_exists('curl_init') ) {
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $host);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_USERAGENT, 'geoPlugin PHP Class
v1.0');
curl_setopt ($ch, CURLOPT_CONNECTTIMEOUT, $this->timeout);
curl_setopt ($ch, CURLOPT_TIMEOUT, $this->timeout);
$response = curl_exec($ch);
curl_close ($ch);
} else if ( ini_get('allow_url_fopen') ) {
$response = file_get_contents($host, 'r');
} else {
trigger_error ('geoPlugin class Error: Cannot retrieve data. Either
compile PHP with cURL support or enable allow_url_fopen in php.ini ',
E_USER_ERROR);
return;
}
return $response;
}
function convert($amount, $float=2, $symbol=true) {
if ( !is_numeric($this->currencyConverter) ||
$this->currencyConverter == 0 ) {
trigger_error('geoPlugin class Notice: currencyConverter has no
value.', E_USER_NOTICE);
return $amount;
}
if ( !is_numeric($amount) ) {
trigger_error ('geoPlugin class Warning: The amount passed to
geoPlugin::convert is not numeric.', E_USER_WARNING);
return $amount;
}
if ( $symbol === true ) {
return $this->currencySymbol . round( ($amount *
$this->currencyConverter), $float );
} else {
return round( ($amount * $this->currencyConverter), $float );
}
}
}
PK�6�[wtW�
index.htmlnu�[���<html><body></body></html>PK�6�[�]����boxpacker/Box.phpnu�[���PK�6�[~MR��"boxpacker/BoxList.phpnu�[���PK�6�[�Ywܷ�boxpacker/ConstrainedItem.phpnu�[���PK�6�[Ǟ��MM&
boxpacker/ConstrainedPlacementItem.phpnu�[���PK�6�[�i�#�boxpacker/index.htmlnu�[���PK�6�[Fh
QQ
boxpacker/Item.phpnu�[���PK�6�[
�QQ�boxpacker/ItemList.phpnu�[���PK�6�[Fh���#8boxpacker/ItemTooLargeException.phpnu�[���PK�6�[|\O�llboxpacker/LayerStabiliser.phpnu�[���PK�6�[]���DD�
boxpacker/OrientatedItem.phpnu�[���PK�6�[4Y�(�(#U)boxpacker/OrientatedItemFactory.phpnu�[���PK�6�[��_P���Rboxpacker/PackedBox.phpnu�[���PK�6�[!k� � �eboxpacker/PackedBoxList.phpnu�[���PK�6�[
�����oboxpacker/PackedItem.phpnu�[���PK�6�[�0p�JJ�wboxpacker/PackedItemList.phpnu�[���PK�6�[�����}boxpacker/PackedLayer.phpnu�[���PK�6�[������boxpacker/Packer.phpnu�[���PK�6�[_��>(>(�boxpacker/VolumePacker.phpnu�[���PK�6�[Q�,���!��boxpacker/WeightRedistributor.phpnu�[���PK�6�[Y�>
zz��boxpacker/WorkingVolume.phpnu�[���PK�6�[�
YO@@
��boxpacker.phpnu�[���PK�6�["h�bss
��compat.phpnu�[���PK�6�[P��M!T!T��expression.phpnu�[���PK�6�[��~ة
�
2geolocation.phpnu�[���PK�6�[B�DW��
�<geoplugin.phpnu�[���PK�6�[wtW�
Jindex.htmlnu�[���PK�tJ