<?php namespace HashOver;// Copyright (C) 2018-2021 Jacob Barkdull// This file is part of HashOver.//// HashOver is free software: you can redistribute it and/or modify// it under the terms of the GNU Affero General Public License as// published by the Free Software Foundation, either version 3 of the// License, or (at your option) any later version.//// HashOver is distributed in the hope that it will be useful,// but WITHOUT ANY WARRANTY; without even the implied warranty of// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the// GNU Affero General Public License for more details.//// You should have received a copy of the GNU Affero General Public License// along with HashOver.  If not, see <http://www.gnu.org/licenses/>.class JavaScriptBuild{	protected $directory;	protected $files = array ();	public function __construct ($directory = '.')	{		$this->changeDirectory ($directory);	}	public function changeDirectory ($directory = '.')	{		$this->directory = trim ($directory, '/') . '/';	}	protected function addFile ($file)	{		// Add file to files array if it isn't already present		if (!in_array ($file, $this->files, true)) {			$this->files[] = $file;		}	}	protected function addDependencies ($file, array $dependencies)	{		// Add each dependency to files array		foreach ($dependencies as $dependency) {			$dependency = $this->directory . $dependency;			// Check if the file exists			if (file_exists ($file)) {				// If so, add file to files array				$this->addFile ($dependency);			} else {				// If not, throw exception on failure				throw new \Exception (sprintf (					'"%s" depends on "%s" but it does not exist.',					$file, $dependency				));			}		}		return true;	}	protected function includeFile ($file)	{		// Attempt to read JavaScript file		$file = @file_get_contents ($file);		// Check if the file read successfully		if ($file !== false) {			// If so, return the contents			return trim ($file);		}		// Otherwise throw exception		throw new \Exception (			sprintf ('Unable to include "%s"', $file)		);	}	public function registerFile ($file, array $options = array ())	{		$file = $this->directory . $file;		if (!empty ($options)) {			// Check if there is an include condition			if (isset ($options['include'])) {				// If so, return void if include is false				if ($options['include'] === false) {					return;				}			}			// Add optional dependencies to files array			if (!empty ($options['dependencies'])) {				$dependencies = $options['dependencies'];				$this->addDependencies ($file, $dependencies);			}		}		// Check if the file exists		if (file_exists ($file)) {			// If so, add file to files array			$this->addFile ($file);		} else {			// If not, throw exception			throw new \Exception (				sprintf ('"%s" does not exist.', $file)			);		}		return true;	}	public function build ($minify = false, $minify_level = 0)	{		// Array for included JavaScript files		$files = array ();		// Attempt to include registered JavaScript files		foreach ($this->files as $file) {			$files[] = $this->includeFile ($file);		}		// Join the included JavaScript files		$javascript = implode (PHP_EOL . PHP_EOL, $files);		// Minify the JavaScript if told to		if (!isset ($_GET['unminified'])) {			if ($minify === true and $minify_level > 0) {				// Instantiate JavaScript minification class				$minifier = new JavaScriptMinifier ();				// Minify JavaScript build result				$minified = $minifier->minify ($javascript, $minify_level);				// Set minified result as JavaScript output				$javascript = $minified;			}		}		// Return normal JavaScript code		return $javascript;	}}