From 6725d487c748e9778c8e6ef5ded40b941ddcd03e Mon Sep 17 00:00:00 2001 From: bandit-ibayashi Date: Fri, 18 Sep 2020 11:55:17 +0900 Subject: [PATCH] V1.0.0 --- CloudPRNTSDKSamples/.gitignore | 362 ++++++++++++++++++ CloudPRNTSDKSamples/CloudPRNTSDKSamples.sln | 25 ++ CloudPRNTSDKSamples/cputil/Program.cs | 247 ++++++++++++ CloudPRNTSDKSamples/cputil/cputil.csproj | 22 ++ CloudPRNTSDKSamples/cputil/readme.md | 290 ++++++++++++++ ExampleServers/php_queue/cloudprnt.php | 351 +++++++++++++++++ ExampleServers/php_queue/cpphp.css | 48 +++ ExampleServers/php_queue/devices.php | 102 +++++ .../php_queue/js/jquery-3.3.1.min.js | 2 + ExampleServers/php_queue/js/management.js | 126 ++++++ ExampleServers/php_queue/management.html | 28 ++ ExampleServers/php_queue/print.html | 27 ++ ExampleServers/php_queue/print.php | 95 +++++ ExampleServers/php_queue/queues.php | 86 +++++ ExampleServers/php_queue/simplequeue.sqlite | Bin 0 -> 11264 bytes ExampleServers/readme.md | 72 ++++ LICENSE | 35 ++ 17 files changed, 1918 insertions(+) create mode 100644 CloudPRNTSDKSamples/.gitignore create mode 100644 CloudPRNTSDKSamples/CloudPRNTSDKSamples.sln create mode 100644 CloudPRNTSDKSamples/cputil/Program.cs create mode 100644 CloudPRNTSDKSamples/cputil/cputil.csproj create mode 100644 CloudPRNTSDKSamples/cputil/readme.md create mode 100755 ExampleServers/php_queue/cloudprnt.php create mode 100755 ExampleServers/php_queue/cpphp.css create mode 100755 ExampleServers/php_queue/devices.php create mode 100755 ExampleServers/php_queue/js/jquery-3.3.1.min.js create mode 100755 ExampleServers/php_queue/js/management.js create mode 100644 ExampleServers/php_queue/management.html create mode 100644 ExampleServers/php_queue/print.html create mode 100755 ExampleServers/php_queue/print.php create mode 100755 ExampleServers/php_queue/queues.php create mode 100755 ExampleServers/php_queue/simplequeue.sqlite create mode 100644 ExampleServers/readme.md create mode 100644 LICENSE diff --git a/CloudPRNTSDKSamples/.gitignore b/CloudPRNTSDKSamples/.gitignore new file mode 100644 index 0000000..3a8542d --- /dev/null +++ b/CloudPRNTSDKSamples/.gitignore @@ -0,0 +1,362 @@ +## Ignore Visual Studio temporary files, build results, and +## files generated by popular Visual Studio add-ons. +## +## Get latest from https://github.com/github/gitignore/blob/master/VisualStudio.gitignore + +# User-specific files +*.rsuser +*.suo +*.user +*.userosscache +*.sln.docstates + +# User-specific files (MonoDevelop/Xamarin Studio) +*.userprefs + +# Mono auto generated files +mono_crash.* + +# Build results +[Dd]ebug/ +[Dd]ebugPublic/ +[Rr]elease/ +[Rr]eleases/ +x64/ +x86/ +[Ww][Ii][Nn]32/ +[Aa][Rr][Mm]/ +[Aa][Rr][Mm]64/ +bld/ +[Bb]in/ +[Oo]bj/ +[Ll]og/ +[Ll]ogs/ + +# Visual Studio 2015/2017 cache/options directory +.vs/ +# Uncomment if you have tasks that create the project's static files in wwwroot +#wwwroot/ + +# Visual Studio 2017 auto generated files +Generated\ Files/ + +# MSTest test Results +[Tt]est[Rr]esult*/ +[Bb]uild[Ll]og.* + +# NUnit +*.VisualState.xml +TestResult.xml +nunit-*.xml + +# Build Results of an ATL Project +[Dd]ebugPS/ +[Rr]eleasePS/ +dlldata.c + +# Benchmark Results +BenchmarkDotNet.Artifacts/ + +# .NET Core +project.lock.json +project.fragment.lock.json +artifacts/ + +# ASP.NET Scaffolding +ScaffoldingReadMe.txt + +# StyleCop +StyleCopReport.xml + +# Files built by Visual Studio +*_i.c +*_p.c +*_h.h +*.ilk +*.meta +*.obj +*.iobj +*.pch +*.pdb +*.ipdb +*.pgc +*.pgd +*.rsp +*.sbr +*.tlb +*.tli +*.tlh +*.tmp +*.tmp_proj +*_wpftmp.csproj +*.log +*.vspscc +*.vssscc +.builds +*.pidb +*.svclog +*.scc + +# Chutzpah Test files +_Chutzpah* + +# Visual C++ cache files +ipch/ +*.aps +*.ncb +*.opendb +*.opensdf +*.sdf +*.cachefile +*.VC.db +*.VC.VC.opendb + +# Visual Studio profiler +*.psess +*.vsp +*.vspx +*.sap + +# Visual Studio Trace Files +*.e2e + +# TFS 2012 Local Workspace +$tf/ + +# Guidance Automation Toolkit +*.gpState + +# ReSharper is a .NET coding add-in +_ReSharper*/ +*.[Rr]e[Ss]harper +*.DotSettings.user + +# TeamCity is a build add-in +_TeamCity* + +# DotCover is a Code Coverage Tool +*.dotCover + +# AxoCover is a Code Coverage Tool +.axoCover/* +!.axoCover/settings.json + +# Coverlet is a free, cross platform Code Coverage Tool +coverage*.json +coverage*.xml +coverage*.info + +# Visual Studio code coverage results +*.coverage +*.coveragexml + +# NCrunch +_NCrunch_* +.*crunch*.local.xml +nCrunchTemp_* + +# MightyMoose +*.mm.* +AutoTest.Net/ + +# Web workbench (sass) +.sass-cache/ + +# Installshield output folder +[Ee]xpress/ + +# DocProject is a documentation generator add-in +DocProject/buildhelp/ +DocProject/Help/*.HxT +DocProject/Help/*.HxC +DocProject/Help/*.hhc +DocProject/Help/*.hhk +DocProject/Help/*.hhp +DocProject/Help/Html2 +DocProject/Help/html + +# Click-Once directory +publish/ + +# Publish Web Output +*.[Pp]ublish.xml +*.azurePubxml +# Note: Comment the next line if you want to checkin your web deploy settings, +# but database connection strings (with potential passwords) will be unencrypted +*.pubxml +*.publishproj + +# Microsoft Azure Web App publish settings. Comment the next line if you want to +# checkin your Azure Web App publish settings, but sensitive information contained +# in these scripts will be unencrypted +PublishScripts/ + +# NuGet Packages +*.nupkg +# NuGet Symbol Packages +*.snupkg +# The packages folder can be ignored because of Package Restore +**/[Pp]ackages/* +# except build/, which is used as an MSBuild target. +!**/[Pp]ackages/build/ +# Uncomment if necessary however generally it will be regenerated when needed +#!**/[Pp]ackages/repositories.config +# NuGet v3's project.json files produces more ignorable files +*.nuget.props +*.nuget.targets + +# Microsoft Azure Build Output +csx/ +*.build.csdef + +# Microsoft Azure Emulator +ecf/ +rcf/ + +# Windows Store app package directories and files +AppPackages/ +BundleArtifacts/ +Package.StoreAssociation.xml +_pkginfo.txt +*.appx +*.appxbundle +*.appxupload + +# Visual Studio cache files +# files ending in .cache can be ignored +*.[Cc]ache +# but keep track of directories ending in .cache +!?*.[Cc]ache/ + +# Others +ClientBin/ +~$* +*~ +*.dbmdl +*.dbproj.schemaview +*.jfm +*.pfx +*.publishsettings +orleans.codegen.cs + +# Including strong name files can present a security risk +# (https://github.com/github/gitignore/pull/2483#issue-259490424) +#*.snk + +# Since there are multiple workflows, uncomment next line to ignore bower_components +# (https://github.com/github/gitignore/pull/1529#issuecomment-104372622) +#bower_components/ + +# RIA/Silverlight projects +Generated_Code/ + +# Backup & report files from converting an old project file +# to a newer Visual Studio version. Backup files are not needed, +# because we have git ;-) +_UpgradeReport_Files/ +Backup*/ +UpgradeLog*.XML +UpgradeLog*.htm +ServiceFabricBackup/ +*.rptproj.bak + +# SQL Server files +*.mdf +*.ldf +*.ndf + +# Business Intelligence projects +*.rdl.data +*.bim.layout +*.bim_*.settings +*.rptproj.rsuser +*- [Bb]ackup.rdl +*- [Bb]ackup ([0-9]).rdl +*- [Bb]ackup ([0-9][0-9]).rdl + +# Microsoft Fakes +FakesAssemblies/ + +# GhostDoc plugin setting file +*.GhostDoc.xml + +# Node.js Tools for Visual Studio +.ntvs_analysis.dat +node_modules/ + +# Visual Studio 6 build log +*.plg + +# Visual Studio 6 workspace options file +*.opt + +# Visual Studio 6 auto-generated workspace file (contains which files were open etc.) +*.vbw + +# Visual Studio LightSwitch build output +**/*.HTMLClient/GeneratedArtifacts +**/*.DesktopClient/GeneratedArtifacts +**/*.DesktopClient/ModelManifest.xml +**/*.Server/GeneratedArtifacts +**/*.Server/ModelManifest.xml +_Pvt_Extensions + +# Paket dependency manager +.paket/paket.exe +paket-files/ + +# FAKE - F# Make +.fake/ + +# CodeRush personal settings +.cr/personal + +# Python Tools for Visual Studio (PTVS) +__pycache__/ +*.pyc + +# Cake - Uncomment if you are using it +# tools/** +# !tools/packages.config + +# Tabs Studio +*.tss + +# Telerik's JustMock configuration file +*.jmconfig + +# BizTalk build output +*.btp.cs +*.btm.cs +*.odx.cs +*.xsd.cs + +# OpenCover UI analysis results +OpenCover/ + +# Azure Stream Analytics local run output +ASALocalRun/ + +# MSBuild Binary and Structured Log +*.binlog + +# NVidia Nsight GPU debugger configuration file +*.nvuser + +# MFractors (Xamarin productivity tool) working folder +.mfractor/ + +# Local History for Visual Studio +.localhistory/ + +# BeatPulse healthcheck temp database +healthchecksdb + +# Backup folder for Package Reference Convert tool in Visual Studio 2017 +MigrationBackup/ + +# Ionide (cross platform F# VS Code tools) working folder +.ionide/ + +# Fody - auto-generated XML schema +FodyWeavers.xsd \ No newline at end of file diff --git a/CloudPRNTSDKSamples/CloudPRNTSDKSamples.sln b/CloudPRNTSDKSamples/CloudPRNTSDKSamples.sln new file mode 100644 index 0000000..9ca5e8f --- /dev/null +++ b/CloudPRNTSDKSamples/CloudPRNTSDKSamples.sln @@ -0,0 +1,25 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio 15 +VisualStudioVersion = 15.0.28010.2003 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "cputil", "cputil\cputil.csproj", "{AAE267F1-6DAA-492B-9565-75875115AAA9}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Release|Any CPU = Release|Any CPU + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {AAE267F1-6DAA-492B-9565-75875115AAA9}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {AAE267F1-6DAA-492B-9565-75875115AAA9}.Debug|Any CPU.Build.0 = Debug|Any CPU + {AAE267F1-6DAA-492B-9565-75875115AAA9}.Release|Any CPU.ActiveCfg = Release|Any CPU + {AAE267F1-6DAA-492B-9565-75875115AAA9}.Release|Any CPU.Build.0 = Release|Any CPU + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(ExtensibilityGlobals) = postSolution + SolutionGuid = {C2F8067F-B97A-4F2D-800F-FC7586AC88BF} + EndGlobalSection +EndGlobal diff --git a/CloudPRNTSDKSamples/cputil/Program.cs b/CloudPRNTSDKSamples/cputil/Program.cs new file mode 100644 index 0000000..ad5f062 --- /dev/null +++ b/CloudPRNTSDKSamples/cputil/Program.cs @@ -0,0 +1,247 @@ +using System; +using System.IO; +using System.Reflection; +using System.Collections.Generic; +using StarMicronics.CloudPrnt; + +using Newtonsoft.Json; + +namespace cputil +{ + class Program + { + static ConversionOptions opts = new ConversionOptions(); + + static void Main(string[] args) + { + opts.JobEndCutType = CutType.Full; + opts.JobEndFeedToCutter = true; + + for (int i = 0; i < args.Length; i++) + { + switch (args[i].ToLower()) + { + case "help": + PrintHelp(); + break; + + case "version": + case "--version": // Common practive to support this flag on Linux + DisplayInfo(); + break; + + case "jsonstatus": + Console.WriteLine(ConvertStatusToJson(args[++i])); + break; + + case "mediatypes": + { + string[] outputList = Document.GetOutputTypesFromFileName(args[++i]); + Console.WriteLine(JsonConvert.SerializeObject(outputList)); + } + break; + + case "mediatypes-mime": + { + string[] outputList = Document.GetOutputTypesFromType(args[++i]); + Console.WriteLine(JsonConvert.SerializeObject(outputList)); + } + break; + + case "supportedinputs": + PrintInputs(); + break; + + case "decode": + if(args.Length - i < 3) + { + PrintHelp(); + break; + } + + string format = args[++i]; + string filename = args[++i]; + string outputfile = args[++i]; + + Stream s = null; + + if (outputfile == "-" || outputfile == "" || outputfile == "[stdout]") + s = Console.OpenStandardOutput(); + else + s = new FileStream(outputfile, FileMode.Create); + + //decode(format, filename, s); + Document.ConvertFile(filename, s, format, opts); + s.Close(); + + Console.Error.WriteLine(String.Format("Wrote output to \"{0}\"", outputfile)); + break; + + case "printarea": + if(args.Length - i < 1) + { + PrintHelp(); + break; + } + int printableArea = 0; + string printarea_length = args[++i]; + bool result = int.TryParse(printarea_length, out printableArea); + + if (result) + opts.DeviceWidth = printableArea; + else + Console.Error.WriteLine("Input value is incorrect. Please set correct value. e.g.) \"printarea XXX(X is numeric)\" "); + + break; + + case "matrix57.5": + opts.DeviceWidth = 160; + break; + + case "matrix69.5": + opts.DeviceWidth = 190; + break; + + case "matrix3": + case "matrix76": + opts.DeviceWidth = 210; + break; + + case "thermal2": + case "thermal58": + opts.DeviceWidth = 48 * 8; + break; + + case "thermal3": + case "thermal80": + opts.DeviceWidth = 576; + break; + + case "thermal82": + case "thermal83": + opts.DeviceWidth = 640; + break; + + case "thermal4": + case "thermal112": + opts.DeviceWidth = 832; + break; + + case "utf8": + opts.SupportUTF8 = true; + break; + + case "scale-to-fit": + opts.ScaleToFit = true; + break; + + case "dither": + opts.PerformDither = true; + break; + + case "nodither": + opts.PerformDither = false; + break; + + case "fullcut": + opts.JobEndCutType = CutType.Full; + break; + + case "partialcut": + opts.JobEndCutType = CutType.Partial; + break; + + case "waitkey": + Console.ReadKey(); + break; + } + } + + if (args.Length == 0) + PrintHelp(); + + } + + static void PrintHelp() + { + String help = String.Join(Environment.NewLine, + "cputil - Star CloudPRNT helper utility", + "======================================", + "", + "Options:", + " help - display this help message.", + " version - display version information.", + " supportedinputs - list supported input data formats, as a JSON array.", + " jsonstatus - Convert cloudPRNT reported ASB status into JSON", + " mediatypes - Test the specified file and report which media", + " types can be decoded to as a JSON array.", + " mediatypes-mime - Report which output media formats are supported", + " for conversion from a specified input media type.", + " should be specified as an IANA/MIME", + " formatted media content type string, for example", + " \"image/png\" or \"application/vnd.star.markup\".", + " decode - Convert file to the specified format. Format should", + " be provides as a media type string.", + " decoder data is writtenn to the file specified by", + " . If output is set to \"-\" or \"[stdout]\"", + " then data will be written to standard output.", + " thermal2/thermal58 - set device constraints for a thermal 58mm/2\" printer", + " thermal3/thermal80 - set device constraints for a thermal 80mm/3\" printer", + " thermal82/thermal83 - set device constraints for a thermal 82mm/83mm printer", + " thermal4/thermal112 - set device constraints for a thermal 112mm/4\" printer", + " matrix57.5 - set device constraints for a dot-matrix 57.5mm\" printer", + " matrix69.5 - set device constraints for a dot-matrix 69.5mm\" printer", + " matrix3/matrix76 - set device constraints for a dot-matrix 76mm/3\" printer", + " printarea - set device constraints for a specified printable area dot size of printer", + " utf8 - specify that the target device supports UTF8 encoding", + " dither - specify that colour/greyscale images should be ditherer", + " scale-to-fit - specify that any images which exceed the device width", + " should be resized to fit the page.", + " fullcut - request a full cut at the end of the print job, only if", + " the input job format does not specify a cut method.", + " partialcut - request a partial cut at the end of the print job, only", + " if the input job format does not specify a cut method.", + " waitkey - wait for a key press, use as last parameter when", + " it is useful to see the output of other options."); + + Console.WriteLine(help); + } + + static void DisplayInfo() + { + Assembly a = typeof(StarMicronics.CloudPrnt.Document).Assembly; + AssemblyName n = a.GetName(); + Version v = n.Version; + + Console.WriteLine("{0}: {1}.{2}.{3}.{4}", n.Name, v.Major, v.Minor, v.Build, v.Revision); + Console.WriteLine("cputil: 1.0.0.0"); + } + + static void PrintInputs() + { + string[] inputs = new string[] + { + "text/plain", + "text/vnd.star.markup", + "image/png", + "image/jpeg", + "image/bmp", + "image/gif" + }; + Console.WriteLine(JsonConvert.SerializeObject(inputs, Formatting.Indented)); + } + + static string ConvertStatusToJson(string status) + { + PrinterStatus stat = new PrinterStatus(status); + + return JsonConvert.SerializeObject(stat, Formatting.Indented); + } + + static string GetOutputMediatTypes(string filename) + { + return JsonConvert.SerializeObject(Document.GetOutputTypesFromFileName(filename)); + } + + } +} diff --git a/CloudPRNTSDKSamples/cputil/cputil.csproj b/CloudPRNTSDKSamples/cputil/cputil.csproj new file mode 100644 index 0000000..a9eef70 --- /dev/null +++ b/CloudPRNTSDKSamples/cputil/cputil.csproj @@ -0,0 +1,22 @@ + + + + Exe + netcoreapp2.1 + Star Micronics + Star Micronics + Copyright 2019 Star Micronics Co., Ltd. + + + + + + + + + + Always + + + + diff --git a/CloudPRNTSDKSamples/cputil/readme.md b/CloudPRNTSDKSamples/cputil/readme.md new file mode 100644 index 0000000..6725ce6 --- /dev/null +++ b/CloudPRNTSDKSamples/cputil/readme.md @@ -0,0 +1,290 @@ +# 1. Overview + + +This package contains cputil Ver 1.0.0. +cputil is intented to serve and a useful back-end tool to help with implementing CloudPRNT servers that are not .Net or .Net Core based. + +Cputil can be use on any platform supported by .Net Core 2.1 including: + +- Windows x86 and x64 + + cputil-win-x86_v100.zip / cputil-win-x64_v100.zip +- Linux x64 + + cputil-linux-x64_v100.tar.gz +- Apple Mac OS (OSX) x64 (Except 10.15 or later) + + cputil-osx-x64_v100.tar.gz +- Linux Arm (Raspberry PI compatible) + + cputil-linux-arm_v100.tar.gz + +In all cases, it is possible to build a self contained package that can be run on the desired platform without the need for a .Net Framework or .Net Core installation. + +Please refer to SDK documents for details. +(http://www.starmicronics.com/support/SDKDocumentation.aspx - CloudPRNT -> Documents) + + +# 2. Contents + +~~~ +cputil-_v100.zip(or .tar.gz) +|- Readme_En.txt // Release Notes (English) +|- Readme_Jp.txt // Release Notes (Japanese) +|- SoftwareLicenseAgreement.pdf // Software License Agreement (English) +|- SoftwareLicenseAgreement_Jp.pdf // Software License Agreement (Japanese) +| ++- cputil- + |- cputil(.exe) // cputil executable file +~~~ + +# 3. Scope + +Cputil can be use on any platform supported by .Net Core 2.1 including: + +- Windows x86 and x64 + + cputil-win-x86_v100.zip / cputil-win-x64_v100.zip +- Linux x64 + + cputil-linux-x64_v100.tar.gz +- Apple Mac OS (OSX) x64 (Except 10.15 or later) + + cputil-osx-x64_v100.tar.gz +- Linux Arm (Raspberry PI compatible) + + cputil-linux-arm_v100.tar.gz + +Works with these CloudPRNT client printers: + +- mC-Print2 +- mC-Print3 +- TSP650II with IFBD-HI01X +- TSP700II with IFBD-HI01X +- TSP800II with IFBD-HI01X +- SP700 with IFBD-HI02X + +Please refer to each CloudPRNT client printer for details. +You can download the manual from Star web site. + +# 4. Usage Example + +The example of usages for cputil are like below. + +And it also can be refer to SDK documents for details. +(http://www.starmicronics.com/support/SDKDocumentation.aspx - CloudPRNT -> Documents) + +## Installation + +Please unzip/extract cputil-.zip(or .tar.gz) to any specified path on PC. +(Installation location and method is entirely the choice of the server administrator) + +The below operation is to test this "Usage Example". Please open the terminal or command prompt on each PC and perform following command. + +- Windows + ~~~ + > cd \cputil-win-x64_v100\cputil-win-x64 + or + > cd \cputil-win-x86_v100\cputil-win-x86 + ~~~ + +- Linux + ~~~ + $ cd /cputil-linux-x64 + ~~~ + +- macOS + ~~~ + $ cd /cputil-osx-x64 + ~~~ + +## Decoding Star ASB Status + +Star CloudPRNT devices will report their status in Star ASB format, as a string of 7 or more hexadecimal values. For Example: + +~~~ +> "23 86 00 00 00 00 00 00 00 00 00" +~~~ + +This is not easy to decode in all languages, and do cputil provides a method to convert this into JSON format data, e.g.: + +- Windows + ~~~ + > .\cputil.exe jsonstatus "23 86 00 00 00 00 00 00 00 00 00" + ~~~ + +- Linux / macOS + ~~~ + $ ./cputil jsonstatus "23 86 00 00 00 00 00 00 00 00 00" + ~~~ + +will generate the output: + +~~~ +> { +> "Online": true, +> "CoverOpen": false, +> "CompulsionSwitch": false, +> "OverTemperature": false, +> "Recoverable": true, +> "CutterError": false, +> "MechanicalError": false, +> "ReceiveBufferOverflow": false, +> "BlackMarkError": false, +> "PresenterPaperJam": false, +> "VoltageError": false, +> "PaperEmpty": false, +> "PaperLow": false +> } +~~~ + + +## Handling Print Job media formats + +Cputil can help with key parts of the CloudPRNT printing process. +A server can prepare a print job in a single input format, which may not be natively supported by the \cloudPRNT client device. +The server can then use cputil to convert the job, as needed to a format that the CloudPRNT client does support. + +Supported input print job media formats are: + +- Images + + PNG - image/png + + Jpeg - image/jpeg + + BMP - image/bmp + + GIF - image/gif +- Plain Text - text/plain +- Star Document Markup - text/vnd.star.markup + + +### generating the mediaTypes field + +When a CloudPRNT compatible server has a print job ready for a particular client (typically a Star mC-Print2, mC-Print3 or printer with HI0x interface card), the it must: + +- wait for a poll request from the client (a JSON request sent by http POST) +- reply to the client with a suitable json response, with at least the fields: + + @jobReady@ set to true. + + @mediaTypes@ an array of media type names in which the job can be provided to the client. + +For example: + +~~~ +> { +> "jobReady": true, +> "mediaTypes": ["image/jpeg", "image/png"] +> } +~~~ + +At this point in the job printing negotiation, cputil can be used to prepare the mediaTypes list, based on the input format that the server plans to use. + +For example, for a server that will use a PNG image as the initial print job source,use (In this sample, sourceimage.png is the name of the input file. +Please prepare and put the file to directory same as cputil executable): + +- Windows + ~~~ + > .\cputil.exe mediatypes sourceimage.png + ~~~ + +- Linux / macOS + ~~~ + $ ./cputil mediatypes sourceimage.png + ~~~ + +which will generate the JSON ready output: + + ~~~ + > ["image/png","image/jpeg","application/vnd.star.raster","application/vnd.star.line","application/vnd.star.starprnt","application/vnd.star.starprntcore"] + ~~~ + + +## Converting a job for printing + +After a server has provided a JSON response to the CloudPRNT poll with the jobReady field set to true, and a valid mediaTypes list, the client will recognise that it is there is a job for it to print. +It will perfom the following steps: + +- select its preferred mediaType, from those available in the list. This is typically selected based on the first format in the list which is supported by the client. However, the exact decision can be client specific. +- Perform an http GET to the CloudPRNT server to retrieve the job, specifying the chosen mediaType through a query string parameter. + +When the server receives the http GET, it should return the job to be printer encoded with the requested media type. + +Servers can prepare the job in a single, internally preferred format and then use cputil to convert it to the requested format. + +For example, if a server has prepared a print job as png data, and the client requests it as StarPRNT printer command data (application/vnd.star.starprnt) then cputil can be used: + +- Windows + + ~~~ + > .\cputil.exe decode "application/vnd.star.starprnt" sourceimage.png outputdata.bin + ~~~ + +- Linux / macOS + + ~~~ + $ ./cputil decode "application/vnd.star.starprnt" sourceimage.png outputdata.bin + ~~~ + +Which will convert the png input file into printer command data stored in "outputdata.bin". If it is more convenient to write the output data to standard output, then use either "-" ot "[stdout]" as the output file name. + +And this outputdata.bin can print on the starprnt emulation printer(mC-Print2/3) via 9100 port / CloudPRNT print job etc. + +## Conversion options + +Conversion can include image scaling or cropping and dithering. +For scaling and cropping to work, it is necessary to inform cputil of the printer print width. CloudPRNT servers can obtain this information through the CloudPRNT clientAction "PageInfo" request. + +To specify the print area size, use one of the following options: + +- "thermal2" or "thermal58" + + set the print area to that of a 2inch/58mm printer, such as the mC-Print2. +- "thermal3" or "thermal80" + + set the print area to that of a 3inch/80mm printer, such as a TSP650II or mC-Print3. +- "thermal4" or "thermal112" + + set the print area to that of a 4inch/112mm printer, such as the Star TSP800II. + +To specify dithering, use the option "dither". +To specify that the image should be scaled to fit the print area, use the "scale-to-fit" option. Otherwise the image will be unscales, but cropped if it is wider than the print area. + +For example, to prepare print data as StarPRNT commands for a 2inch printer from a PNG source, with dithering and the image scaled to fit the page: + +- Windows + + For 2inch printer(mC-Print2): + + ~~~ + > .\cputil.exe thermal2 dither scale-to-fit decode "application/vnd.star.starprnt" sourceimage.png outputdata_2.bin + ~~~ + + + For 3inch printer(mC-Print3): + + ~~~ + > .\cputil.exe thermal3 dither scale-to-fit decode "application/vnd.star.starprnt" sourceimage.png outputdata_3.bin + ~~~ + +- Linux / macOS + + For 2inch printer(mC-Print2): + + ~~~ + $ ./cputil thermal2 dither scale-to-fit decode "application/vnd.star.starprnt" sourceimage.png outputdata_2.bin + ~~~ + + + For 3inch printer(mC-Print3): + ~~~ + $ ./cputil thermal3 dither scale-to-fit decode "application/vnd.star.starprnt" sourceimage.png outputdata_3.bin + ~~~ + +# 5. Limitation + +1. In macOS environment, 10.15 or later are not supported. + +2. Word wrapping / column command for starmarkup features with Unicode character are only supported by mC-Print2 / mC-Print3 / TSP650II. + + +# 6. OSS Licenses + +Cputil package includes these libraries which is included OSS licenses. + +- .NET core (MIT License) + + https://github.com/dotnet/core/blob/master/LICENSE.TXT +- SixLabors.ImageSharpe (Apache License) + + http://www.apache.org/licenses/LICENSE-2.0 +- Newtonsoft.Json (MIT License) + + https://github.com/dotnet/core/blob/master/LICENSE.TXT + +# 7. Copyright + +Copyright 2019 Star Micronics Co., Ltd. All rights reserved. + +# 8. Release History + +- Ver.1.0.0 (2019/11/05) + + First release. diff --git a/ExampleServers/php_queue/cloudprnt.php b/ExampleServers/php_queue/cloudprnt.php new file mode 100755 index 0000000..2b1d9b9 --- /dev/null +++ b/ExampleServers/php_queue/cloudprnt.php @@ -0,0 +1,351 @@ +query("SELECT Header, Footer, Logo, Coupon FROM Queues WHERE id = '" .$queue."'"); + + if (isset($results)) { + $row = $results->fetchArray(); // fetch next row + + if (isset($row) && !empty($row)) { + $qfields['Header'] = $row['header']; + $qfields['Footer'] = $row['footer']; + $qfields['Logo'] = $row['logo']; + $qfields['Coupon'] = $row['coupon']; + } else { + // error message + } + } + + return $qfields; +} + +function handleCloudPRNTGetJob($db) { + $content_type = $_GET['type']; // determine the media type that the cloudPRNT device is requesting + // and set it as the content type for this GET response + // create temporary files for storing the source print job and the version converted to the format requested by the cloudprnt device + // NOTE: using temporary files is usually very fast, because they will be generated in /tmp which is generally a RAM based filesystem + // but, this depends on the OS and distribution. If these files will be written to physical media then it may harm performance + // and cause unnecessary writes to disk. + $basefile = tempnam(sys_get_temp_dir(), "markup"); + $markupfile = $basefile.".stm"; // cputil used the filename to determing the format of the job that it is to convert + $outputfile = tempnam(sys_get_temp_dir(), "output"); + + list($position, $queue, $width) = getDevicePrintingRequired($db, $_GET['mac']); // Find which queue and position is pending for this printer + $ticketDesign = getQueuePrintParameters($db, $queue); // Get design fields for this queue + + renderMarkupJob($markupfile, $position, $queue, $ticketDesign); + + getCPConvertedJob($markupfile, $content_type, $width, $outputfile); // convert the Star Markup job into the format requested + // by the CloudPRNT device + header("Content-Type: ".$content_type); + header("Content-Length: ".filesize($outputfile)); + readfile($outputfile); // return the converted job as the GET response + + // clean up the temporary files + unlink($basefile); + unlink($markupfile); + unlink($outputfile); +} + +/* + Get a list of supported input types from "cputil" for a given input type +*/ +function getCPSupportedOutputs($input) { + global $cputilpath; + $file = popen($cputilpath." mediatypes-mime \"text/vnd.star.markup\"", "r"); + + if ($file != FALSE) { + $output = fread($file, 8192); + + pclose($file); + return json_decode($output); + } + + return ""; +} + +/* + Determine whether printing is required for a particular printer, buy checking it's 'Printing' field + which will be set to the position number to be printer when a job is required. + Return the position, queue ID and device print width if printing is required +*/ +function getDevicePrintingRequired($db, $mac) { + $results = $db->query("SELECT Printing, QueueID, DotWidth FROM Devices WHERE DeviceMac = '".$mac."'"); + + if (isset($results)) { + $row = $results->fetchArray(); // fetch next row + + if (!isset($row) || (count($row) < 1)) { + return array(NULL, NULL, NULL); + } else { + return array(intval($row['Printing']), intval($row['QueueID']), intval($row['DotWidth'])); + } + } else { + // error message + } +} + +/* + Query the database and return the stored print width for the device. + This will be used by cputil for correctly formatting the print job. +*/ +function getDeviceOutputWidth($db, $mac) { + $results = $db->query("SELECT DotWidth FROM Devices WHERE DeviceMac = '".$mac."'"); + $width; + + if (isset($results)) { + $row = $results->fetchArray(); // fetch next row + + if (!isset($row) || (count($row) < 1)) { + return 0; + } else { + $width = intval($row['DotWidth']); + + if (!isset($width)) { + $width = 0; + } + + return $width; + } + } else { + // error message + } +} + +function setDeviceInfo($db, $mac, $width, $clientType, $clientVer) { + $affected = $db->query("UPDATE Devices SET 'DotWidth' = '".$width."', 'ClientType' = '".$clientType."', 'ClientVersion' = '" .$clientVer."' WHERE DeviceMac = '" .$mac."';"); + + if (!isset($affected)) { + // error message + } +} + +/* + Update the device status and timestamp in the database. + Returns true if the device exists, of false if no printer is registered in the database + the specified mac address. +*/ +function setDeviceStatus($db, $mac, $status) { + $tstamp = time(); // Store time simply as number of seconds since 1970-01-01 00:00:00+0000 (UTC) + $affected = $db->query("UPDATE Devices SET 'Status' = '".$status."', 'LastPoll' = '".$tstamp."' WHERE DeviceMac = '".$mac."';"); + + if (empty($affected)) { + return false; + } + + return true; +} + +function handleCloudPRNTPoll($db) { + // get the request body, which should be in json format, and parse it + $parsed = json_decode(file_get_contents("php://input"), true); + + $pollResponse = array(); + $pollResponse['jobReady'] = false; // set jobReady to false by default, this is enough to provide the minimum cloudprnt response + //$pollResponse['deleteMethod'] = "GET"; // set jobReady to false by default, this is enough to provide the minimum cloudprnt response + + $deviceRegistered = setDeviceStatus($db, $parsed['printerMAC'], urldecode($parsed['statusCode'])); + + if (!$deviceRegistered) { + // the request came from a printer that is not currently registered in the database. + // just do nothing, allow jobReady to return false so that the cloudPrnt device doesn't take any action + // Note: this can be a good time to print a 'welcome' job if required + } elseif (isset($parsed['clientAction'])) { + // client action responses received, meaning that the cloudPRNT device has responded to a + // request from the server. This server will request print/paper size and the client type/version when needed + $width = 0; + $ctype = ""; + $cver = ""; + + $client_actions = $parsed['clientAction']; + + for ($i = 0; $i < count($client_actions); $i++) { + if ($client_actions[$i]['request'] === "PageInfo") { + $width = intval($client_actions[$i]['result']['printWidth']) * intval($client_actions[$i]['result']['horizontalResolution']); + } elseif ($client_actions[$i]['request'] === "ClientType") { + $ctype = strval($client_actions[$i]['result']); + } elseif ($client_actions[$i]['request'] === "ClientVersion") { + $cver = strval($client_actions[$i]['result']); + } + } + + setDeviceInfo($db, $parsed['printerMAC'], $width, $ctype, $cver); + } else { + // obtain printer device info, to see if this has been stored in the database + $printWidth = getDeviceOutputWidth($db, $parsed['printerMAC']); + + if (intval($printWidth) === 0) { + // if the device width is not stored in the database, then use a client action to request it, and other device infor at the same time + $pollResponse['clientAction'] = array(); + $pollResponse['clientAction'][0] = array("request" => "PageInfo", "options" => ""); + $pollResponse['clientAction'][1] = array("request" => "ClientType", "options" => ""); + $pollResponse['clientAction'][2] = array("request" => "ClientVersion", "options" => ""); + } else { + // No client action is needed, so check the database to see if a ticket has been requested + list($printing, $queue, $dotwidth) = getDevicePrintingRequired($db, $parsed['printerMAC']); + + if (isset($printing) && !empty($printing) && isset($queue)) { + // a ticket has been requested, so let the device know that printing is needed + $pollResponse['jobReady'] = true; + + // this queuing sample will always use Star Markup to define the print job, so get a list of + // output formats that can be generated from a Star markup job by cputil and return it. + // the device will select one format from this list, based on it's internal compatibility and capabilities + $pollResponse['mediaTypes'] = getCPSupportedOutputs("text/vnd.star.markup"); + } + } + } + + header("Content-Type: application/json"); + print_r(json_encode($pollResponse)); +} + +/* + Clear a print job from the database, for the specified printer, but setting it's 'Position' field to 'null' +*/ +function setCompleteJob($db, $mac) { + $affected = $db->query("UPDATE Devices SET 'Printing' = 0 WHERE DeviceMac = '".$mac."';"); + + if (!isset($affected)) { + // error message + } +} + +/* + Handle http DELETE requests which are used by the CloudPRNT device to clear a print job from the server. + Usually the request is due to the job having printed sucesfully, but it may also be due to an error + such as the job media type being incompatible, too large or corrupt. +*/ +function handleCloudPRNTDelete($db) { + $clearJobFromDB = true; + + $headercode = substr($_GET['code'], 0, 1); + + if ($headercode != "2") { + // job has not printed due to an error + $fullcode = substr($_GET['code'], 0, 3); + + if ($fullcode === "520") { // download timeout + $clearJobFromDB = false; // do not clear the job in this case, since the cause is more likely to be a network issue + } + + // error message + } + + if ($clearJobFromDB) { + setCompleteJob($db, $_GET['mac']); + } +} + +if (!isset($db) || empty($db)) { + http_response_code(500); +} elseif ($_SERVER['REQUEST_METHOD'] === "GET") { + if(strpos($_SERVER['QUERY_STRING'], "&delete") !== false) { // if server set "deleteMethod":"GET" in POST response + handleCloudPRNTDelete($db); + } else { // Request a content of print job + handleCloudPRNTGetJob($db); + } +} elseif ($_SERVER['REQUEST_METHOD'] === "POST") { + handleCloudPRNTPoll($db); +} elseif ($_SERVER['REQUEST_METHOD'] === "DELETE") { + handleCloudPRNTDelete($db); +} else { + http_response_code(405); +} + +$db->close(); +?> diff --git a/ExampleServers/php_queue/cpphp.css b/ExampleServers/php_queue/cpphp.css new file mode 100755 index 0000000..e7d8f4e --- /dev/null +++ b/ExampleServers/php_queue/cpphp.css @@ -0,0 +1,48 @@ +body { + background-color: lightblue; + margin: 0; + padding: 10pt 0 0 0; + text-align: center; + vertical-align: middle; + font-family: Verdana, Geneva, Tahoma, sans-serif; +} + +p { + padding: 0; + margin: 10px 0 0 0; +} + +.printButton { + width: 50%; + height: 50%; + text-align: center; + vertical-align: middle; + display: inline-block; + background-color: lightslategrey; + border-radius: 10pt; + padding: 40pt; + cursor: pointer; + font-family: Verdana, Geneva, Tahoma, sans-serif; + font-size: xx-large; + color: whitesmoke; + +} + +.printButton:hover { + background-color: steelblue; +} + +.cpurl { + background-color: whitesmoke; + font-weight: bold; + border-color: black; + border-style: solid; + border-width: 1px; + border-radius: 4px; + padding: 4px; + display: inline-block; +} + +.datagrid table { border-collapse: collapse; text-align: left; } +.datagrid {font: normal 12px/150% Arial, Helvetica, sans-serif; display: inline-block; background: #fff; overflow: hidden; border: 1px solid #000000; border-radius: 8px; } +.datagrid table td, .datagrid table th { padding: 4px 7px; }.datagrid table thead th {background:-webkit-gradient( linear, left top, left bottom, color-stop(0.05, #8195E6), color-stop(1, #004669) );background:-moz-linear-gradient( center top, #8195E6 5%, #004669 100% );filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#8195E6', endColorstr='#004669');background-color:#8195E6; color:#FFFFFF; font-size: 15px; font-weight: bold; } .datagrid table thead th:first-child { border: none; }.datagrid table tbody td { color: #000A0F; font-size: 14px;font-weight: normal; }.datagrid table tbody .alt td { background: #E1EEF4; color: #000A0F; }.datagrid table tbody td:first-child { border-left: none; }.datagrid table tbody tr:last-child td { border-bottom: none; }.datagrid table tfoot td div { border-top: 1px solid #000000;background: #E1EEF4;} .datagrid table tfoot td { padding: 0; font-size: 12px } .datagrid table tfoot td div{ padding: 2px; } diff --git a/ExampleServers/php_queue/devices.php b/ExampleServers/php_queue/devices.php new file mode 100755 index 0000000..fe85898 --- /dev/null +++ b/ExampleServers/php_queue/devices.php @@ -0,0 +1,102 @@ +query("INSERT INTO `Devices`(DeviceMac, QueueID) VALUES ('".$mac."', '".$queue."');"); + + if (!isset($affected)) { + http_response_code(500); + } +} + +function delDevice($db, $mac) { + $affected = $db->query("DELETE FROM `Devices` WHERE `DeviceMac`='".$mac."';"); + + if (!isset($affected)) { + http_response_code(500); + } +} + +function listDevices($db) { + global $deviceTimeout; + $results = $db->query("SELECT DeviceMac, Status, QueueID, Queues.name, ClientType, ClientVersion, LastPoll FROM Devices INNER JOIN Queues ON Queues.id = Devices.QueueID"); + $rdata = array(); + $count = 0; + + if (isset($results)) { + $now = time(); + + while ($row = $results->fetchArray()) { + $lpt = 0; // last polling time + + if (intval($row['LastPoll']) > 0) { + $lpt = intval($row['LastPoll']); + } + + $secondsElapsed = intval($now) - intval($lpt); + + $rdata[$count] = array("mac" => strval($row['DeviceMac'])); + + if (intval($secondsElapsed) < intval($deviceTimeout)) { + $rdata[$count] += array("status" => strval($row['Status'])); + } else { + $rdata[$count] += array("status" => "Connection Lost"); + } + + $rdata[$count] += array("queueId" => strval($row['QueueID'])); + $rdata[$count] += array("queueName" => strval($row['name'])); + $rdata[$count] += array("clientType" => strval($row['ClientType'])); + $rdata[$count] += array("clientVersion" => strval($row['ClientVersion'])); + $rdata[$count] += array("lastConnection" => strval($row['LastPoll'])); + $rdata[$count] += array("lastPolledTime" => strval($secondsElapsed)); + + $count++; + } + + header("Content-Type: application/json"); + print_r(json_encode($rdata)); + } else { + http_response_code(500); + } +} + +function handleGETRequest() { + $dbname = "simplequeue.sqlite"; // database file name + $db = new SQLite3($dbname); + + if (!empty($_GET['new'])) { + $new = $_GET['new']; + } + + if (!empty($_GET['queue'])) { + $queue = $_GET['queue']; + } + + if (!empty($_GET['del'])) { + $del = $_GET['del']; + } + + if (!isset($db) || empty($db)) { + http_response_code(500); + return; + } + + if (isset($new) && isset($queue)) { + addDevice($db, $new, $queue); + } elseif (isset($del)) { + delDevice($db, $del); + } else { + listDevices($db); + } + + $db->close(); +} + +if ($_SERVER['REQUEST_METHOD'] === "GET") { + handleGETRequest(); +} else { + http_response_code(405); +} +?> diff --git a/ExampleServers/php_queue/js/jquery-3.3.1.min.js b/ExampleServers/php_queue/js/jquery-3.3.1.min.js new file mode 100755 index 0000000..4d9b3a2 --- /dev/null +++ b/ExampleServers/php_queue/js/jquery-3.3.1.min.js @@ -0,0 +1,2 @@ +/*! jQuery v3.3.1 | (c) JS Foundation and other contributors | jquery.org/license */ +!function(e,t){"use strict";"object"==typeof module&&"object"==typeof module.exports?module.exports=e.document?t(e,!0):function(e){if(!e.document)throw new Error("jQuery requires a window with a document");return t(e)}:t(e)}("undefined"!=typeof window?window:this,function(e,t){"use strict";var n=[],r=e.document,i=Object.getPrototypeOf,o=n.slice,a=n.concat,s=n.push,u=n.indexOf,l={},c=l.toString,f=l.hasOwnProperty,p=f.toString,d=p.call(Object),h={},g=function e(t){return"function"==typeof t&&"number"!=typeof t.nodeType},y=function e(t){return null!=t&&t===t.window},v={type:!0,src:!0,noModule:!0};function m(e,t,n){var i,o=(t=t||r).createElement("script");if(o.text=e,n)for(i in v)n[i]&&(o[i]=n[i]);t.head.appendChild(o).parentNode.removeChild(o)}function x(e){return null==e?e+"":"object"==typeof e||"function"==typeof e?l[c.call(e)]||"object":typeof e}var b="3.3.1",w=function(e,t){return new w.fn.init(e,t)},T=/^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g;w.fn=w.prototype={jquery:"3.3.1",constructor:w,length:0,toArray:function(){return o.call(this)},get:function(e){return null==e?o.call(this):e<0?this[e+this.length]:this[e]},pushStack:function(e){var t=w.merge(this.constructor(),e);return t.prevObject=this,t},each:function(e){return w.each(this,e)},map:function(e){return this.pushStack(w.map(this,function(t,n){return e.call(t,n,t)}))},slice:function(){return this.pushStack(o.apply(this,arguments))},first:function(){return this.eq(0)},last:function(){return this.eq(-1)},eq:function(e){var t=this.length,n=+e+(e<0?t:0);return this.pushStack(n>=0&&n0&&t-1 in e)}var E=function(e){var t,n,r,i,o,a,s,u,l,c,f,p,d,h,g,y,v,m,x,b="sizzle"+1*new Date,w=e.document,T=0,C=0,E=ae(),k=ae(),S=ae(),D=function(e,t){return e===t&&(f=!0),0},N={}.hasOwnProperty,A=[],j=A.pop,q=A.push,L=A.push,H=A.slice,O=function(e,t){for(var n=0,r=e.length;n+~]|"+M+")"+M+"*"),z=new RegExp("="+M+"*([^\\]'\"]*?)"+M+"*\\]","g"),X=new RegExp(W),U=new RegExp("^"+R+"$"),V={ID:new RegExp("^#("+R+")"),CLASS:new RegExp("^\\.("+R+")"),TAG:new RegExp("^("+R+"|[*])"),ATTR:new RegExp("^"+I),PSEUDO:new RegExp("^"+W),CHILD:new RegExp("^:(only|first|last|nth|nth-last)-(child|of-type)(?:\\("+M+"*(even|odd|(([+-]|)(\\d*)n|)"+M+"*(?:([+-]|)"+M+"*(\\d+)|))"+M+"*\\)|)","i"),bool:new RegExp("^(?:"+P+")$","i"),needsContext:new RegExp("^"+M+"*[>+~]|:(even|odd|eq|gt|lt|nth|first|last)(?:\\("+M+"*((?:-\\d)?\\d*)"+M+"*\\)|)(?=[^-]|$)","i")},G=/^(?:input|select|textarea|button)$/i,Y=/^h\d$/i,Q=/^[^{]+\{\s*\[native \w/,J=/^(?:#([\w-]+)|(\w+)|\.([\w-]+))$/,K=/[+~]/,Z=new RegExp("\\\\([\\da-f]{1,6}"+M+"?|("+M+")|.)","ig"),ee=function(e,t,n){var r="0x"+t-65536;return r!==r||n?t:r<0?String.fromCharCode(r+65536):String.fromCharCode(r>>10|55296,1023&r|56320)},te=/([\0-\x1f\x7f]|^-?\d)|^-$|[^\0-\x1f\x7f-\uFFFF\w-]/g,ne=function(e,t){return t?"\0"===e?"\ufffd":e.slice(0,-1)+"\\"+e.charCodeAt(e.length-1).toString(16)+" ":"\\"+e},re=function(){p()},ie=me(function(e){return!0===e.disabled&&("form"in e||"label"in e)},{dir:"parentNode",next:"legend"});try{L.apply(A=H.call(w.childNodes),w.childNodes),A[w.childNodes.length].nodeType}catch(e){L={apply:A.length?function(e,t){q.apply(e,H.call(t))}:function(e,t){var n=e.length,r=0;while(e[n++]=t[r++]);e.length=n-1}}}function oe(e,t,r,i){var o,s,l,c,f,h,v,m=t&&t.ownerDocument,T=t?t.nodeType:9;if(r=r||[],"string"!=typeof e||!e||1!==T&&9!==T&&11!==T)return r;if(!i&&((t?t.ownerDocument||t:w)!==d&&p(t),t=t||d,g)){if(11!==T&&(f=J.exec(e)))if(o=f[1]){if(9===T){if(!(l=t.getElementById(o)))return r;if(l.id===o)return r.push(l),r}else if(m&&(l=m.getElementById(o))&&x(t,l)&&l.id===o)return r.push(l),r}else{if(f[2])return L.apply(r,t.getElementsByTagName(e)),r;if((o=f[3])&&n.getElementsByClassName&&t.getElementsByClassName)return L.apply(r,t.getElementsByClassName(o)),r}if(n.qsa&&!S[e+" "]&&(!y||!y.test(e))){if(1!==T)m=t,v=e;else if("object"!==t.nodeName.toLowerCase()){(c=t.getAttribute("id"))?c=c.replace(te,ne):t.setAttribute("id",c=b),s=(h=a(e)).length;while(s--)h[s]="#"+c+" "+ve(h[s]);v=h.join(","),m=K.test(e)&&ge(t.parentNode)||t}if(v)try{return L.apply(r,m.querySelectorAll(v)),r}catch(e){}finally{c===b&&t.removeAttribute("id")}}}return u(e.replace(B,"$1"),t,r,i)}function ae(){var e=[];function t(n,i){return e.push(n+" ")>r.cacheLength&&delete t[e.shift()],t[n+" "]=i}return t}function se(e){return e[b]=!0,e}function ue(e){var t=d.createElement("fieldset");try{return!!e(t)}catch(e){return!1}finally{t.parentNode&&t.parentNode.removeChild(t),t=null}}function le(e,t){var n=e.split("|"),i=n.length;while(i--)r.attrHandle[n[i]]=t}function ce(e,t){var n=t&&e,r=n&&1===e.nodeType&&1===t.nodeType&&e.sourceIndex-t.sourceIndex;if(r)return r;if(n)while(n=n.nextSibling)if(n===t)return-1;return e?1:-1}function fe(e){return function(t){return"input"===t.nodeName.toLowerCase()&&t.type===e}}function pe(e){return function(t){var n=t.nodeName.toLowerCase();return("input"===n||"button"===n)&&t.type===e}}function de(e){return function(t){return"form"in t?t.parentNode&&!1===t.disabled?"label"in t?"label"in t.parentNode?t.parentNode.disabled===e:t.disabled===e:t.isDisabled===e||t.isDisabled!==!e&&ie(t)===e:t.disabled===e:"label"in t&&t.disabled===e}}function he(e){return se(function(t){return t=+t,se(function(n,r){var i,o=e([],n.length,t),a=o.length;while(a--)n[i=o[a]]&&(n[i]=!(r[i]=n[i]))})})}function ge(e){return e&&"undefined"!=typeof e.getElementsByTagName&&e}n=oe.support={},o=oe.isXML=function(e){var t=e&&(e.ownerDocument||e).documentElement;return!!t&&"HTML"!==t.nodeName},p=oe.setDocument=function(e){var t,i,a=e?e.ownerDocument||e:w;return a!==d&&9===a.nodeType&&a.documentElement?(d=a,h=d.documentElement,g=!o(d),w!==d&&(i=d.defaultView)&&i.top!==i&&(i.addEventListener?i.addEventListener("unload",re,!1):i.attachEvent&&i.attachEvent("onunload",re)),n.attributes=ue(function(e){return e.className="i",!e.getAttribute("className")}),n.getElementsByTagName=ue(function(e){return e.appendChild(d.createComment("")),!e.getElementsByTagName("*").length}),n.getElementsByClassName=Q.test(d.getElementsByClassName),n.getById=ue(function(e){return h.appendChild(e).id=b,!d.getElementsByName||!d.getElementsByName(b).length}),n.getById?(r.filter.ID=function(e){var t=e.replace(Z,ee);return function(e){return e.getAttribute("id")===t}},r.find.ID=function(e,t){if("undefined"!=typeof t.getElementById&&g){var n=t.getElementById(e);return n?[n]:[]}}):(r.filter.ID=function(e){var t=e.replace(Z,ee);return function(e){var n="undefined"!=typeof e.getAttributeNode&&e.getAttributeNode("id");return n&&n.value===t}},r.find.ID=function(e,t){if("undefined"!=typeof t.getElementById&&g){var n,r,i,o=t.getElementById(e);if(o){if((n=o.getAttributeNode("id"))&&n.value===e)return[o];i=t.getElementsByName(e),r=0;while(o=i[r++])if((n=o.getAttributeNode("id"))&&n.value===e)return[o]}return[]}}),r.find.TAG=n.getElementsByTagName?function(e,t){return"undefined"!=typeof t.getElementsByTagName?t.getElementsByTagName(e):n.qsa?t.querySelectorAll(e):void 0}:function(e,t){var n,r=[],i=0,o=t.getElementsByTagName(e);if("*"===e){while(n=o[i++])1===n.nodeType&&r.push(n);return r}return o},r.find.CLASS=n.getElementsByClassName&&function(e,t){if("undefined"!=typeof t.getElementsByClassName&&g)return t.getElementsByClassName(e)},v=[],y=[],(n.qsa=Q.test(d.querySelectorAll))&&(ue(function(e){h.appendChild(e).innerHTML="",e.querySelectorAll("[msallowcapture^='']").length&&y.push("[*^$]="+M+"*(?:''|\"\")"),e.querySelectorAll("[selected]").length||y.push("\\["+M+"*(?:value|"+P+")"),e.querySelectorAll("[id~="+b+"-]").length||y.push("~="),e.querySelectorAll(":checked").length||y.push(":checked"),e.querySelectorAll("a#"+b+"+*").length||y.push(".#.+[+~]")}),ue(function(e){e.innerHTML="";var t=d.createElement("input");t.setAttribute("type","hidden"),e.appendChild(t).setAttribute("name","D"),e.querySelectorAll("[name=d]").length&&y.push("name"+M+"*[*^$|!~]?="),2!==e.querySelectorAll(":enabled").length&&y.push(":enabled",":disabled"),h.appendChild(e).disabled=!0,2!==e.querySelectorAll(":disabled").length&&y.push(":enabled",":disabled"),e.querySelectorAll("*,:x"),y.push(",.*:")})),(n.matchesSelector=Q.test(m=h.matches||h.webkitMatchesSelector||h.mozMatchesSelector||h.oMatchesSelector||h.msMatchesSelector))&&ue(function(e){n.disconnectedMatch=m.call(e,"*"),m.call(e,"[s!='']:x"),v.push("!=",W)}),y=y.length&&new RegExp(y.join("|")),v=v.length&&new RegExp(v.join("|")),t=Q.test(h.compareDocumentPosition),x=t||Q.test(h.contains)?function(e,t){var n=9===e.nodeType?e.documentElement:e,r=t&&t.parentNode;return e===r||!(!r||1!==r.nodeType||!(n.contains?n.contains(r):e.compareDocumentPosition&&16&e.compareDocumentPosition(r)))}:function(e,t){if(t)while(t=t.parentNode)if(t===e)return!0;return!1},D=t?function(e,t){if(e===t)return f=!0,0;var r=!e.compareDocumentPosition-!t.compareDocumentPosition;return r||(1&(r=(e.ownerDocument||e)===(t.ownerDocument||t)?e.compareDocumentPosition(t):1)||!n.sortDetached&&t.compareDocumentPosition(e)===r?e===d||e.ownerDocument===w&&x(w,e)?-1:t===d||t.ownerDocument===w&&x(w,t)?1:c?O(c,e)-O(c,t):0:4&r?-1:1)}:function(e,t){if(e===t)return f=!0,0;var n,r=0,i=e.parentNode,o=t.parentNode,a=[e],s=[t];if(!i||!o)return e===d?-1:t===d?1:i?-1:o?1:c?O(c,e)-O(c,t):0;if(i===o)return ce(e,t);n=e;while(n=n.parentNode)a.unshift(n);n=t;while(n=n.parentNode)s.unshift(n);while(a[r]===s[r])r++;return r?ce(a[r],s[r]):a[r]===w?-1:s[r]===w?1:0},d):d},oe.matches=function(e,t){return oe(e,null,null,t)},oe.matchesSelector=function(e,t){if((e.ownerDocument||e)!==d&&p(e),t=t.replace(z,"='$1']"),n.matchesSelector&&g&&!S[t+" "]&&(!v||!v.test(t))&&(!y||!y.test(t)))try{var r=m.call(e,t);if(r||n.disconnectedMatch||e.document&&11!==e.document.nodeType)return r}catch(e){}return oe(t,d,null,[e]).length>0},oe.contains=function(e,t){return(e.ownerDocument||e)!==d&&p(e),x(e,t)},oe.attr=function(e,t){(e.ownerDocument||e)!==d&&p(e);var i=r.attrHandle[t.toLowerCase()],o=i&&N.call(r.attrHandle,t.toLowerCase())?i(e,t,!g):void 0;return void 0!==o?o:n.attributes||!g?e.getAttribute(t):(o=e.getAttributeNode(t))&&o.specified?o.value:null},oe.escape=function(e){return(e+"").replace(te,ne)},oe.error=function(e){throw new Error("Syntax error, unrecognized expression: "+e)},oe.uniqueSort=function(e){var t,r=[],i=0,o=0;if(f=!n.detectDuplicates,c=!n.sortStable&&e.slice(0),e.sort(D),f){while(t=e[o++])t===e[o]&&(i=r.push(o));while(i--)e.splice(r[i],1)}return c=null,e},i=oe.getText=function(e){var t,n="",r=0,o=e.nodeType;if(o){if(1===o||9===o||11===o){if("string"==typeof e.textContent)return e.textContent;for(e=e.firstChild;e;e=e.nextSibling)n+=i(e)}else if(3===o||4===o)return e.nodeValue}else while(t=e[r++])n+=i(t);return n},(r=oe.selectors={cacheLength:50,createPseudo:se,match:V,attrHandle:{},find:{},relative:{">":{dir:"parentNode",first:!0}," ":{dir:"parentNode"},"+":{dir:"previousSibling",first:!0},"~":{dir:"previousSibling"}},preFilter:{ATTR:function(e){return e[1]=e[1].replace(Z,ee),e[3]=(e[3]||e[4]||e[5]||"").replace(Z,ee),"~="===e[2]&&(e[3]=" "+e[3]+" "),e.slice(0,4)},CHILD:function(e){return e[1]=e[1].toLowerCase(),"nth"===e[1].slice(0,3)?(e[3]||oe.error(e[0]),e[4]=+(e[4]?e[5]+(e[6]||1):2*("even"===e[3]||"odd"===e[3])),e[5]=+(e[7]+e[8]||"odd"===e[3])):e[3]&&oe.error(e[0]),e},PSEUDO:function(e){var t,n=!e[6]&&e[2];return V.CHILD.test(e[0])?null:(e[3]?e[2]=e[4]||e[5]||"":n&&X.test(n)&&(t=a(n,!0))&&(t=n.indexOf(")",n.length-t)-n.length)&&(e[0]=e[0].slice(0,t),e[2]=n.slice(0,t)),e.slice(0,3))}},filter:{TAG:function(e){var t=e.replace(Z,ee).toLowerCase();return"*"===e?function(){return!0}:function(e){return e.nodeName&&e.nodeName.toLowerCase()===t}},CLASS:function(e){var t=E[e+" "];return t||(t=new RegExp("(^|"+M+")"+e+"("+M+"|$)"))&&E(e,function(e){return t.test("string"==typeof e.className&&e.className||"undefined"!=typeof e.getAttribute&&e.getAttribute("class")||"")})},ATTR:function(e,t,n){return function(r){var i=oe.attr(r,e);return null==i?"!="===t:!t||(i+="","="===t?i===n:"!="===t?i!==n:"^="===t?n&&0===i.indexOf(n):"*="===t?n&&i.indexOf(n)>-1:"$="===t?n&&i.slice(-n.length)===n:"~="===t?(" "+i.replace($," ")+" ").indexOf(n)>-1:"|="===t&&(i===n||i.slice(0,n.length+1)===n+"-"))}},CHILD:function(e,t,n,r,i){var o="nth"!==e.slice(0,3),a="last"!==e.slice(-4),s="of-type"===t;return 1===r&&0===i?function(e){return!!e.parentNode}:function(t,n,u){var l,c,f,p,d,h,g=o!==a?"nextSibling":"previousSibling",y=t.parentNode,v=s&&t.nodeName.toLowerCase(),m=!u&&!s,x=!1;if(y){if(o){while(g){p=t;while(p=p[g])if(s?p.nodeName.toLowerCase()===v:1===p.nodeType)return!1;h=g="only"===e&&!h&&"nextSibling"}return!0}if(h=[a?y.firstChild:y.lastChild],a&&m){x=(d=(l=(c=(f=(p=y)[b]||(p[b]={}))[p.uniqueID]||(f[p.uniqueID]={}))[e]||[])[0]===T&&l[1])&&l[2],p=d&&y.childNodes[d];while(p=++d&&p&&p[g]||(x=d=0)||h.pop())if(1===p.nodeType&&++x&&p===t){c[e]=[T,d,x];break}}else if(m&&(x=d=(l=(c=(f=(p=t)[b]||(p[b]={}))[p.uniqueID]||(f[p.uniqueID]={}))[e]||[])[0]===T&&l[1]),!1===x)while(p=++d&&p&&p[g]||(x=d=0)||h.pop())if((s?p.nodeName.toLowerCase()===v:1===p.nodeType)&&++x&&(m&&((c=(f=p[b]||(p[b]={}))[p.uniqueID]||(f[p.uniqueID]={}))[e]=[T,x]),p===t))break;return(x-=i)===r||x%r==0&&x/r>=0}}},PSEUDO:function(e,t){var n,i=r.pseudos[e]||r.setFilters[e.toLowerCase()]||oe.error("unsupported pseudo: "+e);return i[b]?i(t):i.length>1?(n=[e,e,"",t],r.setFilters.hasOwnProperty(e.toLowerCase())?se(function(e,n){var r,o=i(e,t),a=o.length;while(a--)e[r=O(e,o[a])]=!(n[r]=o[a])}):function(e){return i(e,0,n)}):i}},pseudos:{not:se(function(e){var t=[],n=[],r=s(e.replace(B,"$1"));return r[b]?se(function(e,t,n,i){var o,a=r(e,null,i,[]),s=e.length;while(s--)(o=a[s])&&(e[s]=!(t[s]=o))}):function(e,i,o){return t[0]=e,r(t,null,o,n),t[0]=null,!n.pop()}}),has:se(function(e){return function(t){return oe(e,t).length>0}}),contains:se(function(e){return e=e.replace(Z,ee),function(t){return(t.textContent||t.innerText||i(t)).indexOf(e)>-1}}),lang:se(function(e){return U.test(e||"")||oe.error("unsupported lang: "+e),e=e.replace(Z,ee).toLowerCase(),function(t){var n;do{if(n=g?t.lang:t.getAttribute("xml:lang")||t.getAttribute("lang"))return(n=n.toLowerCase())===e||0===n.indexOf(e+"-")}while((t=t.parentNode)&&1===t.nodeType);return!1}}),target:function(t){var n=e.location&&e.location.hash;return n&&n.slice(1)===t.id},root:function(e){return e===h},focus:function(e){return e===d.activeElement&&(!d.hasFocus||d.hasFocus())&&!!(e.type||e.href||~e.tabIndex)},enabled:de(!1),disabled:de(!0),checked:function(e){var t=e.nodeName.toLowerCase();return"input"===t&&!!e.checked||"option"===t&&!!e.selected},selected:function(e){return e.parentNode&&e.parentNode.selectedIndex,!0===e.selected},empty:function(e){for(e=e.firstChild;e;e=e.nextSibling)if(e.nodeType<6)return!1;return!0},parent:function(e){return!r.pseudos.empty(e)},header:function(e){return Y.test(e.nodeName)},input:function(e){return G.test(e.nodeName)},button:function(e){var t=e.nodeName.toLowerCase();return"input"===t&&"button"===e.type||"button"===t},text:function(e){var t;return"input"===e.nodeName.toLowerCase()&&"text"===e.type&&(null==(t=e.getAttribute("type"))||"text"===t.toLowerCase())},first:he(function(){return[0]}),last:he(function(e,t){return[t-1]}),eq:he(function(e,t,n){return[n<0?n+t:n]}),even:he(function(e,t){for(var n=0;n=0;)e.push(r);return e}),gt:he(function(e,t,n){for(var r=n<0?n+t:n;++r1?function(t,n,r){var i=e.length;while(i--)if(!e[i](t,n,r))return!1;return!0}:e[0]}function be(e,t,n){for(var r=0,i=t.length;r-1&&(o[l]=!(a[l]=f))}}else v=we(v===a?v.splice(h,v.length):v),i?i(null,a,v,u):L.apply(a,v)})}function Ce(e){for(var t,n,i,o=e.length,a=r.relative[e[0].type],s=a||r.relative[" "],u=a?1:0,c=me(function(e){return e===t},s,!0),f=me(function(e){return O(t,e)>-1},s,!0),p=[function(e,n,r){var i=!a&&(r||n!==l)||((t=n).nodeType?c(e,n,r):f(e,n,r));return t=null,i}];u1&&xe(p),u>1&&ve(e.slice(0,u-1).concat({value:" "===e[u-2].type?"*":""})).replace(B,"$1"),n,u0,i=e.length>0,o=function(o,a,s,u,c){var f,h,y,v=0,m="0",x=o&&[],b=[],w=l,C=o||i&&r.find.TAG("*",c),E=T+=null==w?1:Math.random()||.1,k=C.length;for(c&&(l=a===d||a||c);m!==k&&null!=(f=C[m]);m++){if(i&&f){h=0,a||f.ownerDocument===d||(p(f),s=!g);while(y=e[h++])if(y(f,a||d,s)){u.push(f);break}c&&(T=E)}n&&((f=!y&&f)&&v--,o&&x.push(f))}if(v+=m,n&&m!==v){h=0;while(y=t[h++])y(x,b,a,s);if(o){if(v>0)while(m--)x[m]||b[m]||(b[m]=j.call(u));b=we(b)}L.apply(u,b),c&&!o&&b.length>0&&v+t.length>1&&oe.uniqueSort(u)}return c&&(T=E,l=w),x};return n?se(o):o}return s=oe.compile=function(e,t){var n,r=[],i=[],o=S[e+" "];if(!o){t||(t=a(e)),n=t.length;while(n--)(o=Ce(t[n]))[b]?r.push(o):i.push(o);(o=S(e,Ee(i,r))).selector=e}return o},u=oe.select=function(e,t,n,i){var o,u,l,c,f,p="function"==typeof e&&e,d=!i&&a(e=p.selector||e);if(n=n||[],1===d.length){if((u=d[0]=d[0].slice(0)).length>2&&"ID"===(l=u[0]).type&&9===t.nodeType&&g&&r.relative[u[1].type]){if(!(t=(r.find.ID(l.matches[0].replace(Z,ee),t)||[])[0]))return n;p&&(t=t.parentNode),e=e.slice(u.shift().value.length)}o=V.needsContext.test(e)?0:u.length;while(o--){if(l=u[o],r.relative[c=l.type])break;if((f=r.find[c])&&(i=f(l.matches[0].replace(Z,ee),K.test(u[0].type)&&ge(t.parentNode)||t))){if(u.splice(o,1),!(e=i.length&&ve(u)))return L.apply(n,i),n;break}}}return(p||s(e,d))(i,t,!g,n,!t||K.test(e)&&ge(t.parentNode)||t),n},n.sortStable=b.split("").sort(D).join("")===b,n.detectDuplicates=!!f,p(),n.sortDetached=ue(function(e){return 1&e.compareDocumentPosition(d.createElement("fieldset"))}),ue(function(e){return e.innerHTML="","#"===e.firstChild.getAttribute("href")})||le("type|href|height|width",function(e,t,n){if(!n)return e.getAttribute(t,"type"===t.toLowerCase()?1:2)}),n.attributes&&ue(function(e){return e.innerHTML="",e.firstChild.setAttribute("value",""),""===e.firstChild.getAttribute("value")})||le("value",function(e,t,n){if(!n&&"input"===e.nodeName.toLowerCase())return e.defaultValue}),ue(function(e){return null==e.getAttribute("disabled")})||le(P,function(e,t,n){var r;if(!n)return!0===e[t]?t.toLowerCase():(r=e.getAttributeNode(t))&&r.specified?r.value:null}),oe}(e);w.find=E,w.expr=E.selectors,w.expr[":"]=w.expr.pseudos,w.uniqueSort=w.unique=E.uniqueSort,w.text=E.getText,w.isXMLDoc=E.isXML,w.contains=E.contains,w.escapeSelector=E.escape;var k=function(e,t,n){var r=[],i=void 0!==n;while((e=e[t])&&9!==e.nodeType)if(1===e.nodeType){if(i&&w(e).is(n))break;r.push(e)}return r},S=function(e,t){for(var n=[];e;e=e.nextSibling)1===e.nodeType&&e!==t&&n.push(e);return n},D=w.expr.match.needsContext;function N(e,t){return e.nodeName&&e.nodeName.toLowerCase()===t.toLowerCase()}var A=/^<([a-z][^\/\0>:\x20\t\r\n\f]*)[\x20\t\r\n\f]*\/?>(?:<\/\1>|)$/i;function j(e,t,n){return g(t)?w.grep(e,function(e,r){return!!t.call(e,r,e)!==n}):t.nodeType?w.grep(e,function(e){return e===t!==n}):"string"!=typeof t?w.grep(e,function(e){return u.call(t,e)>-1!==n}):w.filter(t,e,n)}w.filter=function(e,t,n){var r=t[0];return n&&(e=":not("+e+")"),1===t.length&&1===r.nodeType?w.find.matchesSelector(r,e)?[r]:[]:w.find.matches(e,w.grep(t,function(e){return 1===e.nodeType}))},w.fn.extend({find:function(e){var t,n,r=this.length,i=this;if("string"!=typeof e)return this.pushStack(w(e).filter(function(){for(t=0;t1?w.uniqueSort(n):n},filter:function(e){return this.pushStack(j(this,e||[],!1))},not:function(e){return this.pushStack(j(this,e||[],!0))},is:function(e){return!!j(this,"string"==typeof e&&D.test(e)?w(e):e||[],!1).length}});var q,L=/^(?:\s*(<[\w\W]+>)[^>]*|#([\w-]+))$/;(w.fn.init=function(e,t,n){var i,o;if(!e)return this;if(n=n||q,"string"==typeof e){if(!(i="<"===e[0]&&">"===e[e.length-1]&&e.length>=3?[null,e,null]:L.exec(e))||!i[1]&&t)return!t||t.jquery?(t||n).find(e):this.constructor(t).find(e);if(i[1]){if(t=t instanceof w?t[0]:t,w.merge(this,w.parseHTML(i[1],t&&t.nodeType?t.ownerDocument||t:r,!0)),A.test(i[1])&&w.isPlainObject(t))for(i in t)g(this[i])?this[i](t[i]):this.attr(i,t[i]);return this}return(o=r.getElementById(i[2]))&&(this[0]=o,this.length=1),this}return e.nodeType?(this[0]=e,this.length=1,this):g(e)?void 0!==n.ready?n.ready(e):e(w):w.makeArray(e,this)}).prototype=w.fn,q=w(r);var H=/^(?:parents|prev(?:Until|All))/,O={children:!0,contents:!0,next:!0,prev:!0};w.fn.extend({has:function(e){var t=w(e,this),n=t.length;return this.filter(function(){for(var e=0;e-1:1===n.nodeType&&w.find.matchesSelector(n,e))){o.push(n);break}return this.pushStack(o.length>1?w.uniqueSort(o):o)},index:function(e){return e?"string"==typeof e?u.call(w(e),this[0]):u.call(this,e.jquery?e[0]:e):this[0]&&this[0].parentNode?this.first().prevAll().length:-1},add:function(e,t){return this.pushStack(w.uniqueSort(w.merge(this.get(),w(e,t))))},addBack:function(e){return this.add(null==e?this.prevObject:this.prevObject.filter(e))}});function P(e,t){while((e=e[t])&&1!==e.nodeType);return e}w.each({parent:function(e){var t=e.parentNode;return t&&11!==t.nodeType?t:null},parents:function(e){return k(e,"parentNode")},parentsUntil:function(e,t,n){return k(e,"parentNode",n)},next:function(e){return P(e,"nextSibling")},prev:function(e){return P(e,"previousSibling")},nextAll:function(e){return k(e,"nextSibling")},prevAll:function(e){return k(e,"previousSibling")},nextUntil:function(e,t,n){return k(e,"nextSibling",n)},prevUntil:function(e,t,n){return k(e,"previousSibling",n)},siblings:function(e){return S((e.parentNode||{}).firstChild,e)},children:function(e){return S(e.firstChild)},contents:function(e){return N(e,"iframe")?e.contentDocument:(N(e,"template")&&(e=e.content||e),w.merge([],e.childNodes))}},function(e,t){w.fn[e]=function(n,r){var i=w.map(this,t,n);return"Until"!==e.slice(-5)&&(r=n),r&&"string"==typeof r&&(i=w.filter(r,i)),this.length>1&&(O[e]||w.uniqueSort(i),H.test(e)&&i.reverse()),this.pushStack(i)}});var M=/[^\x20\t\r\n\f]+/g;function R(e){var t={};return w.each(e.match(M)||[],function(e,n){t[n]=!0}),t}w.Callbacks=function(e){e="string"==typeof e?R(e):w.extend({},e);var t,n,r,i,o=[],a=[],s=-1,u=function(){for(i=i||e.once,r=t=!0;a.length;s=-1){n=a.shift();while(++s-1)o.splice(n,1),n<=s&&s--}),this},has:function(e){return e?w.inArray(e,o)>-1:o.length>0},empty:function(){return o&&(o=[]),this},disable:function(){return i=a=[],o=n="",this},disabled:function(){return!o},lock:function(){return i=a=[],n||t||(o=n=""),this},locked:function(){return!!i},fireWith:function(e,n){return i||(n=[e,(n=n||[]).slice?n.slice():n],a.push(n),t||u()),this},fire:function(){return l.fireWith(this,arguments),this},fired:function(){return!!r}};return l};function I(e){return e}function W(e){throw e}function $(e,t,n,r){var i;try{e&&g(i=e.promise)?i.call(e).done(t).fail(n):e&&g(i=e.then)?i.call(e,t,n):t.apply(void 0,[e].slice(r))}catch(e){n.apply(void 0,[e])}}w.extend({Deferred:function(t){var n=[["notify","progress",w.Callbacks("memory"),w.Callbacks("memory"),2],["resolve","done",w.Callbacks("once memory"),w.Callbacks("once memory"),0,"resolved"],["reject","fail",w.Callbacks("once memory"),w.Callbacks("once memory"),1,"rejected"]],r="pending",i={state:function(){return r},always:function(){return o.done(arguments).fail(arguments),this},"catch":function(e){return i.then(null,e)},pipe:function(){var e=arguments;return w.Deferred(function(t){w.each(n,function(n,r){var i=g(e[r[4]])&&e[r[4]];o[r[1]](function(){var e=i&&i.apply(this,arguments);e&&g(e.promise)?e.promise().progress(t.notify).done(t.resolve).fail(t.reject):t[r[0]+"With"](this,i?[e]:arguments)})}),e=null}).promise()},then:function(t,r,i){var o=0;function a(t,n,r,i){return function(){var s=this,u=arguments,l=function(){var e,l;if(!(t=o&&(r!==W&&(s=void 0,u=[e]),n.rejectWith(s,u))}};t?c():(w.Deferred.getStackHook&&(c.stackTrace=w.Deferred.getStackHook()),e.setTimeout(c))}}return w.Deferred(function(e){n[0][3].add(a(0,e,g(i)?i:I,e.notifyWith)),n[1][3].add(a(0,e,g(t)?t:I)),n[2][3].add(a(0,e,g(r)?r:W))}).promise()},promise:function(e){return null!=e?w.extend(e,i):i}},o={};return w.each(n,function(e,t){var a=t[2],s=t[5];i[t[1]]=a.add,s&&a.add(function(){r=s},n[3-e][2].disable,n[3-e][3].disable,n[0][2].lock,n[0][3].lock),a.add(t[3].fire),o[t[0]]=function(){return o[t[0]+"With"](this===o?void 0:this,arguments),this},o[t[0]+"With"]=a.fireWith}),i.promise(o),t&&t.call(o,o),o},when:function(e){var t=arguments.length,n=t,r=Array(n),i=o.call(arguments),a=w.Deferred(),s=function(e){return function(n){r[e]=this,i[e]=arguments.length>1?o.call(arguments):n,--t||a.resolveWith(r,i)}};if(t<=1&&($(e,a.done(s(n)).resolve,a.reject,!t),"pending"===a.state()||g(i[n]&&i[n].then)))return a.then();while(n--)$(i[n],s(n),a.reject);return a.promise()}});var B=/^(Eval|Internal|Range|Reference|Syntax|Type|URI)Error$/;w.Deferred.exceptionHook=function(t,n){e.console&&e.console.warn&&t&&B.test(t.name)&&e.console.warn("jQuery.Deferred exception: "+t.message,t.stack,n)},w.readyException=function(t){e.setTimeout(function(){throw t})};var F=w.Deferred();w.fn.ready=function(e){return F.then(e)["catch"](function(e){w.readyException(e)}),this},w.extend({isReady:!1,readyWait:1,ready:function(e){(!0===e?--w.readyWait:w.isReady)||(w.isReady=!0,!0!==e&&--w.readyWait>0||F.resolveWith(r,[w]))}}),w.ready.then=F.then;function _(){r.removeEventListener("DOMContentLoaded",_),e.removeEventListener("load",_),w.ready()}"complete"===r.readyState||"loading"!==r.readyState&&!r.documentElement.doScroll?e.setTimeout(w.ready):(r.addEventListener("DOMContentLoaded",_),e.addEventListener("load",_));var z=function(e,t,n,r,i,o,a){var s=0,u=e.length,l=null==n;if("object"===x(n)){i=!0;for(s in n)z(e,t,s,n[s],!0,o,a)}else if(void 0!==r&&(i=!0,g(r)||(a=!0),l&&(a?(t.call(e,r),t=null):(l=t,t=function(e,t,n){return l.call(w(e),n)})),t))for(;s1,null,!0)},removeData:function(e){return this.each(function(){K.remove(this,e)})}}),w.extend({queue:function(e,t,n){var r;if(e)return t=(t||"fx")+"queue",r=J.get(e,t),n&&(!r||Array.isArray(n)?r=J.access(e,t,w.makeArray(n)):r.push(n)),r||[]},dequeue:function(e,t){t=t||"fx";var n=w.queue(e,t),r=n.length,i=n.shift(),o=w._queueHooks(e,t),a=function(){w.dequeue(e,t)};"inprogress"===i&&(i=n.shift(),r--),i&&("fx"===t&&n.unshift("inprogress"),delete o.stop,i.call(e,a,o)),!r&&o&&o.empty.fire()},_queueHooks:function(e,t){var n=t+"queueHooks";return J.get(e,n)||J.access(e,n,{empty:w.Callbacks("once memory").add(function(){J.remove(e,[t+"queue",n])})})}}),w.fn.extend({queue:function(e,t){var n=2;return"string"!=typeof e&&(t=e,e="fx",n--),arguments.length\x20\t\r\n\f]+)/i,he=/^$|^module$|\/(?:java|ecma)script/i,ge={option:[1,""],thead:[1,"","
"],col:[2,"","
"],tr:[2,"","
"],td:[3,"","
"],_default:[0,"",""]};ge.optgroup=ge.option,ge.tbody=ge.tfoot=ge.colgroup=ge.caption=ge.thead,ge.th=ge.td;function ye(e,t){var n;return n="undefined"!=typeof e.getElementsByTagName?e.getElementsByTagName(t||"*"):"undefined"!=typeof e.querySelectorAll?e.querySelectorAll(t||"*"):[],void 0===t||t&&N(e,t)?w.merge([e],n):n}function ve(e,t){for(var n=0,r=e.length;n-1)i&&i.push(o);else if(l=w.contains(o.ownerDocument,o),a=ye(f.appendChild(o),"script"),l&&ve(a),n){c=0;while(o=a[c++])he.test(o.type||"")&&n.push(o)}return f}!function(){var e=r.createDocumentFragment().appendChild(r.createElement("div")),t=r.createElement("input");t.setAttribute("type","radio"),t.setAttribute("checked","checked"),t.setAttribute("name","t"),e.appendChild(t),h.checkClone=e.cloneNode(!0).cloneNode(!0).lastChild.checked,e.innerHTML="",h.noCloneChecked=!!e.cloneNode(!0).lastChild.defaultValue}();var be=r.documentElement,we=/^key/,Te=/^(?:mouse|pointer|contextmenu|drag|drop)|click/,Ce=/^([^.]*)(?:\.(.+)|)/;function Ee(){return!0}function ke(){return!1}function Se(){try{return r.activeElement}catch(e){}}function De(e,t,n,r,i,o){var a,s;if("object"==typeof t){"string"!=typeof n&&(r=r||n,n=void 0);for(s in t)De(e,s,n,r,t[s],o);return e}if(null==r&&null==i?(i=n,r=n=void 0):null==i&&("string"==typeof n?(i=r,r=void 0):(i=r,r=n,n=void 0)),!1===i)i=ke;else if(!i)return e;return 1===o&&(a=i,(i=function(e){return w().off(e),a.apply(this,arguments)}).guid=a.guid||(a.guid=w.guid++)),e.each(function(){w.event.add(this,t,i,r,n)})}w.event={global:{},add:function(e,t,n,r,i){var o,a,s,u,l,c,f,p,d,h,g,y=J.get(e);if(y){n.handler&&(n=(o=n).handler,i=o.selector),i&&w.find.matchesSelector(be,i),n.guid||(n.guid=w.guid++),(u=y.events)||(u=y.events={}),(a=y.handle)||(a=y.handle=function(t){return"undefined"!=typeof w&&w.event.triggered!==t.type?w.event.dispatch.apply(e,arguments):void 0}),l=(t=(t||"").match(M)||[""]).length;while(l--)d=g=(s=Ce.exec(t[l])||[])[1],h=(s[2]||"").split(".").sort(),d&&(f=w.event.special[d]||{},d=(i?f.delegateType:f.bindType)||d,f=w.event.special[d]||{},c=w.extend({type:d,origType:g,data:r,handler:n,guid:n.guid,selector:i,needsContext:i&&w.expr.match.needsContext.test(i),namespace:h.join(".")},o),(p=u[d])||((p=u[d]=[]).delegateCount=0,f.setup&&!1!==f.setup.call(e,r,h,a)||e.addEventListener&&e.addEventListener(d,a)),f.add&&(f.add.call(e,c),c.handler.guid||(c.handler.guid=n.guid)),i?p.splice(p.delegateCount++,0,c):p.push(c),w.event.global[d]=!0)}},remove:function(e,t,n,r,i){var o,a,s,u,l,c,f,p,d,h,g,y=J.hasData(e)&&J.get(e);if(y&&(u=y.events)){l=(t=(t||"").match(M)||[""]).length;while(l--)if(s=Ce.exec(t[l])||[],d=g=s[1],h=(s[2]||"").split(".").sort(),d){f=w.event.special[d]||{},p=u[d=(r?f.delegateType:f.bindType)||d]||[],s=s[2]&&new RegExp("(^|\\.)"+h.join("\\.(?:.*\\.|)")+"(\\.|$)"),a=o=p.length;while(o--)c=p[o],!i&&g!==c.origType||n&&n.guid!==c.guid||s&&!s.test(c.namespace)||r&&r!==c.selector&&("**"!==r||!c.selector)||(p.splice(o,1),c.selector&&p.delegateCount--,f.remove&&f.remove.call(e,c));a&&!p.length&&(f.teardown&&!1!==f.teardown.call(e,h,y.handle)||w.removeEvent(e,d,y.handle),delete u[d])}else for(d in u)w.event.remove(e,d+t[l],n,r,!0);w.isEmptyObject(u)&&J.remove(e,"handle events")}},dispatch:function(e){var t=w.event.fix(e),n,r,i,o,a,s,u=new Array(arguments.length),l=(J.get(this,"events")||{})[t.type]||[],c=w.event.special[t.type]||{};for(u[0]=t,n=1;n=1))for(;l!==this;l=l.parentNode||this)if(1===l.nodeType&&("click"!==e.type||!0!==l.disabled)){for(o=[],a={},n=0;n-1:w.find(i,this,null,[l]).length),a[i]&&o.push(r);o.length&&s.push({elem:l,handlers:o})}return l=this,u\x20\t\r\n\f]*)[^>]*)\/>/gi,Ae=/\s*$/g;function Le(e,t){return N(e,"table")&&N(11!==t.nodeType?t:t.firstChild,"tr")?w(e).children("tbody")[0]||e:e}function He(e){return e.type=(null!==e.getAttribute("type"))+"/"+e.type,e}function Oe(e){return"true/"===(e.type||"").slice(0,5)?e.type=e.type.slice(5):e.removeAttribute("type"),e}function Pe(e,t){var n,r,i,o,a,s,u,l;if(1===t.nodeType){if(J.hasData(e)&&(o=J.access(e),a=J.set(t,o),l=o.events)){delete a.handle,a.events={};for(i in l)for(n=0,r=l[i].length;n1&&"string"==typeof y&&!h.checkClone&&je.test(y))return e.each(function(i){var o=e.eq(i);v&&(t[0]=y.call(this,i,o.html())),Re(o,t,n,r)});if(p&&(i=xe(t,e[0].ownerDocument,!1,e,r),o=i.firstChild,1===i.childNodes.length&&(i=o),o||r)){for(u=(s=w.map(ye(i,"script"),He)).length;f")},clone:function(e,t,n){var r,i,o,a,s=e.cloneNode(!0),u=w.contains(e.ownerDocument,e);if(!(h.noCloneChecked||1!==e.nodeType&&11!==e.nodeType||w.isXMLDoc(e)))for(a=ye(s),r=0,i=(o=ye(e)).length;r0&&ve(a,!u&&ye(e,"script")),s},cleanData:function(e){for(var t,n,r,i=w.event.special,o=0;void 0!==(n=e[o]);o++)if(Y(n)){if(t=n[J.expando]){if(t.events)for(r in t.events)i[r]?w.event.remove(n,r):w.removeEvent(n,r,t.handle);n[J.expando]=void 0}n[K.expando]&&(n[K.expando]=void 0)}}}),w.fn.extend({detach:function(e){return Ie(this,e,!0)},remove:function(e){return Ie(this,e)},text:function(e){return z(this,function(e){return void 0===e?w.text(this):this.empty().each(function(){1!==this.nodeType&&11!==this.nodeType&&9!==this.nodeType||(this.textContent=e)})},null,e,arguments.length)},append:function(){return Re(this,arguments,function(e){1!==this.nodeType&&11!==this.nodeType&&9!==this.nodeType||Le(this,e).appendChild(e)})},prepend:function(){return Re(this,arguments,function(e){if(1===this.nodeType||11===this.nodeType||9===this.nodeType){var t=Le(this,e);t.insertBefore(e,t.firstChild)}})},before:function(){return Re(this,arguments,function(e){this.parentNode&&this.parentNode.insertBefore(e,this)})},after:function(){return Re(this,arguments,function(e){this.parentNode&&this.parentNode.insertBefore(e,this.nextSibling)})},empty:function(){for(var e,t=0;null!=(e=this[t]);t++)1===e.nodeType&&(w.cleanData(ye(e,!1)),e.textContent="");return this},clone:function(e,t){return e=null!=e&&e,t=null==t?e:t,this.map(function(){return w.clone(this,e,t)})},html:function(e){return z(this,function(e){var t=this[0]||{},n=0,r=this.length;if(void 0===e&&1===t.nodeType)return t.innerHTML;if("string"==typeof e&&!Ae.test(e)&&!ge[(de.exec(e)||["",""])[1].toLowerCase()]){e=w.htmlPrefilter(e);try{for(;n=0&&(u+=Math.max(0,Math.ceil(e["offset"+t[0].toUpperCase()+t.slice(1)]-o-u-s-.5))),u}function et(e,t,n){var r=$e(e),i=Fe(e,t,r),o="border-box"===w.css(e,"boxSizing",!1,r),a=o;if(We.test(i)){if(!n)return i;i="auto"}return a=a&&(h.boxSizingReliable()||i===e.style[t]),("auto"===i||!parseFloat(i)&&"inline"===w.css(e,"display",!1,r))&&(i=e["offset"+t[0].toUpperCase()+t.slice(1)],a=!0),(i=parseFloat(i)||0)+Ze(e,t,n||(o?"border":"content"),a,r,i)+"px"}w.extend({cssHooks:{opacity:{get:function(e,t){if(t){var n=Fe(e,"opacity");return""===n?"1":n}}}},cssNumber:{animationIterationCount:!0,columnCount:!0,fillOpacity:!0,flexGrow:!0,flexShrink:!0,fontWeight:!0,lineHeight:!0,opacity:!0,order:!0,orphans:!0,widows:!0,zIndex:!0,zoom:!0},cssProps:{},style:function(e,t,n,r){if(e&&3!==e.nodeType&&8!==e.nodeType&&e.style){var i,o,a,s=G(t),u=Xe.test(t),l=e.style;if(u||(t=Je(s)),a=w.cssHooks[t]||w.cssHooks[s],void 0===n)return a&&"get"in a&&void 0!==(i=a.get(e,!1,r))?i:l[t];"string"==(o=typeof n)&&(i=ie.exec(n))&&i[1]&&(n=ue(e,t,i),o="number"),null!=n&&n===n&&("number"===o&&(n+=i&&i[3]||(w.cssNumber[s]?"":"px")),h.clearCloneStyle||""!==n||0!==t.indexOf("background")||(l[t]="inherit"),a&&"set"in a&&void 0===(n=a.set(e,n,r))||(u?l.setProperty(t,n):l[t]=n))}},css:function(e,t,n,r){var i,o,a,s=G(t);return Xe.test(t)||(t=Je(s)),(a=w.cssHooks[t]||w.cssHooks[s])&&"get"in a&&(i=a.get(e,!0,n)),void 0===i&&(i=Fe(e,t,r)),"normal"===i&&t in Ve&&(i=Ve[t]),""===n||n?(o=parseFloat(i),!0===n||isFinite(o)?o||0:i):i}}),w.each(["height","width"],function(e,t){w.cssHooks[t]={get:function(e,n,r){if(n)return!ze.test(w.css(e,"display"))||e.getClientRects().length&&e.getBoundingClientRect().width?et(e,t,r):se(e,Ue,function(){return et(e,t,r)})},set:function(e,n,r){var i,o=$e(e),a="border-box"===w.css(e,"boxSizing",!1,o),s=r&&Ze(e,t,r,a,o);return a&&h.scrollboxSize()===o.position&&(s-=Math.ceil(e["offset"+t[0].toUpperCase()+t.slice(1)]-parseFloat(o[t])-Ze(e,t,"border",!1,o)-.5)),s&&(i=ie.exec(n))&&"px"!==(i[3]||"px")&&(e.style[t]=n,n=w.css(e,t)),Ke(e,n,s)}}}),w.cssHooks.marginLeft=_e(h.reliableMarginLeft,function(e,t){if(t)return(parseFloat(Fe(e,"marginLeft"))||e.getBoundingClientRect().left-se(e,{marginLeft:0},function(){return e.getBoundingClientRect().left}))+"px"}),w.each({margin:"",padding:"",border:"Width"},function(e,t){w.cssHooks[e+t]={expand:function(n){for(var r=0,i={},o="string"==typeof n?n.split(" "):[n];r<4;r++)i[e+oe[r]+t]=o[r]||o[r-2]||o[0];return i}},"margin"!==e&&(w.cssHooks[e+t].set=Ke)}),w.fn.extend({css:function(e,t){return z(this,function(e,t,n){var r,i,o={},a=0;if(Array.isArray(t)){for(r=$e(e),i=t.length;a1)}});function tt(e,t,n,r,i){return new tt.prototype.init(e,t,n,r,i)}w.Tween=tt,tt.prototype={constructor:tt,init:function(e,t,n,r,i,o){this.elem=e,this.prop=n,this.easing=i||w.easing._default,this.options=t,this.start=this.now=this.cur(),this.end=r,this.unit=o||(w.cssNumber[n]?"":"px")},cur:function(){var e=tt.propHooks[this.prop];return e&&e.get?e.get(this):tt.propHooks._default.get(this)},run:function(e){var t,n=tt.propHooks[this.prop];return this.options.duration?this.pos=t=w.easing[this.easing](e,this.options.duration*e,0,1,this.options.duration):this.pos=t=e,this.now=(this.end-this.start)*t+this.start,this.options.step&&this.options.step.call(this.elem,this.now,this),n&&n.set?n.set(this):tt.propHooks._default.set(this),this}},tt.prototype.init.prototype=tt.prototype,tt.propHooks={_default:{get:function(e){var t;return 1!==e.elem.nodeType||null!=e.elem[e.prop]&&null==e.elem.style[e.prop]?e.elem[e.prop]:(t=w.css(e.elem,e.prop,""))&&"auto"!==t?t:0},set:function(e){w.fx.step[e.prop]?w.fx.step[e.prop](e):1!==e.elem.nodeType||null==e.elem.style[w.cssProps[e.prop]]&&!w.cssHooks[e.prop]?e.elem[e.prop]=e.now:w.style(e.elem,e.prop,e.now+e.unit)}}},tt.propHooks.scrollTop=tt.propHooks.scrollLeft={set:function(e){e.elem.nodeType&&e.elem.parentNode&&(e.elem[e.prop]=e.now)}},w.easing={linear:function(e){return e},swing:function(e){return.5-Math.cos(e*Math.PI)/2},_default:"swing"},w.fx=tt.prototype.init,w.fx.step={};var nt,rt,it=/^(?:toggle|show|hide)$/,ot=/queueHooks$/;function at(){rt&&(!1===r.hidden&&e.requestAnimationFrame?e.requestAnimationFrame(at):e.setTimeout(at,w.fx.interval),w.fx.tick())}function st(){return e.setTimeout(function(){nt=void 0}),nt=Date.now()}function ut(e,t){var n,r=0,i={height:e};for(t=t?1:0;r<4;r+=2-t)i["margin"+(n=oe[r])]=i["padding"+n]=e;return t&&(i.opacity=i.width=e),i}function lt(e,t,n){for(var r,i=(pt.tweeners[t]||[]).concat(pt.tweeners["*"]),o=0,a=i.length;o1)},removeAttr:function(e){return this.each(function(){w.removeAttr(this,e)})}}),w.extend({attr:function(e,t,n){var r,i,o=e.nodeType;if(3!==o&&8!==o&&2!==o)return"undefined"==typeof e.getAttribute?w.prop(e,t,n):(1===o&&w.isXMLDoc(e)||(i=w.attrHooks[t.toLowerCase()]||(w.expr.match.bool.test(t)?dt:void 0)),void 0!==n?null===n?void w.removeAttr(e,t):i&&"set"in i&&void 0!==(r=i.set(e,n,t))?r:(e.setAttribute(t,n+""),n):i&&"get"in i&&null!==(r=i.get(e,t))?r:null==(r=w.find.attr(e,t))?void 0:r)},attrHooks:{type:{set:function(e,t){if(!h.radioValue&&"radio"===t&&N(e,"input")){var n=e.value;return e.setAttribute("type",t),n&&(e.value=n),t}}}},removeAttr:function(e,t){var n,r=0,i=t&&t.match(M);if(i&&1===e.nodeType)while(n=i[r++])e.removeAttribute(n)}}),dt={set:function(e,t,n){return!1===t?w.removeAttr(e,n):e.setAttribute(n,n),n}},w.each(w.expr.match.bool.source.match(/\w+/g),function(e,t){var n=ht[t]||w.find.attr;ht[t]=function(e,t,r){var i,o,a=t.toLowerCase();return r||(o=ht[a],ht[a]=i,i=null!=n(e,t,r)?a:null,ht[a]=o),i}});var gt=/^(?:input|select|textarea|button)$/i,yt=/^(?:a|area)$/i;w.fn.extend({prop:function(e,t){return z(this,w.prop,e,t,arguments.length>1)},removeProp:function(e){return this.each(function(){delete this[w.propFix[e]||e]})}}),w.extend({prop:function(e,t,n){var r,i,o=e.nodeType;if(3!==o&&8!==o&&2!==o)return 1===o&&w.isXMLDoc(e)||(t=w.propFix[t]||t,i=w.propHooks[t]),void 0!==n?i&&"set"in i&&void 0!==(r=i.set(e,n,t))?r:e[t]=n:i&&"get"in i&&null!==(r=i.get(e,t))?r:e[t]},propHooks:{tabIndex:{get:function(e){var t=w.find.attr(e,"tabindex");return t?parseInt(t,10):gt.test(e.nodeName)||yt.test(e.nodeName)&&e.href?0:-1}}},propFix:{"for":"htmlFor","class":"className"}}),h.optSelected||(w.propHooks.selected={get:function(e){var t=e.parentNode;return t&&t.parentNode&&t.parentNode.selectedIndex,null},set:function(e){var t=e.parentNode;t&&(t.selectedIndex,t.parentNode&&t.parentNode.selectedIndex)}}),w.each(["tabIndex","readOnly","maxLength","cellSpacing","cellPadding","rowSpan","colSpan","useMap","frameBorder","contentEditable"],function(){w.propFix[this.toLowerCase()]=this});function vt(e){return(e.match(M)||[]).join(" ")}function mt(e){return e.getAttribute&&e.getAttribute("class")||""}function xt(e){return Array.isArray(e)?e:"string"==typeof e?e.match(M)||[]:[]}w.fn.extend({addClass:function(e){var t,n,r,i,o,a,s,u=0;if(g(e))return this.each(function(t){w(this).addClass(e.call(this,t,mt(this)))});if((t=xt(e)).length)while(n=this[u++])if(i=mt(n),r=1===n.nodeType&&" "+vt(i)+" "){a=0;while(o=t[a++])r.indexOf(" "+o+" ")<0&&(r+=o+" ");i!==(s=vt(r))&&n.setAttribute("class",s)}return this},removeClass:function(e){var t,n,r,i,o,a,s,u=0;if(g(e))return this.each(function(t){w(this).removeClass(e.call(this,t,mt(this)))});if(!arguments.length)return this.attr("class","");if((t=xt(e)).length)while(n=this[u++])if(i=mt(n),r=1===n.nodeType&&" "+vt(i)+" "){a=0;while(o=t[a++])while(r.indexOf(" "+o+" ")>-1)r=r.replace(" "+o+" "," ");i!==(s=vt(r))&&n.setAttribute("class",s)}return this},toggleClass:function(e,t){var n=typeof e,r="string"===n||Array.isArray(e);return"boolean"==typeof t&&r?t?this.addClass(e):this.removeClass(e):g(e)?this.each(function(n){w(this).toggleClass(e.call(this,n,mt(this),t),t)}):this.each(function(){var t,i,o,a;if(r){i=0,o=w(this),a=xt(e);while(t=a[i++])o.hasClass(t)?o.removeClass(t):o.addClass(t)}else void 0!==e&&"boolean"!==n||((t=mt(this))&&J.set(this,"__className__",t),this.setAttribute&&this.setAttribute("class",t||!1===e?"":J.get(this,"__className__")||""))})},hasClass:function(e){var t,n,r=0;t=" "+e+" ";while(n=this[r++])if(1===n.nodeType&&(" "+vt(mt(n))+" ").indexOf(t)>-1)return!0;return!1}});var bt=/\r/g;w.fn.extend({val:function(e){var t,n,r,i=this[0];{if(arguments.length)return r=g(e),this.each(function(n){var i;1===this.nodeType&&(null==(i=r?e.call(this,n,w(this).val()):e)?i="":"number"==typeof i?i+="":Array.isArray(i)&&(i=w.map(i,function(e){return null==e?"":e+""})),(t=w.valHooks[this.type]||w.valHooks[this.nodeName.toLowerCase()])&&"set"in t&&void 0!==t.set(this,i,"value")||(this.value=i))});if(i)return(t=w.valHooks[i.type]||w.valHooks[i.nodeName.toLowerCase()])&&"get"in t&&void 0!==(n=t.get(i,"value"))?n:"string"==typeof(n=i.value)?n.replace(bt,""):null==n?"":n}}}),w.extend({valHooks:{option:{get:function(e){var t=w.find.attr(e,"value");return null!=t?t:vt(w.text(e))}},select:{get:function(e){var t,n,r,i=e.options,o=e.selectedIndex,a="select-one"===e.type,s=a?null:[],u=a?o+1:i.length;for(r=o<0?u:a?o:0;r-1)&&(n=!0);return n||(e.selectedIndex=-1),o}}}}),w.each(["radio","checkbox"],function(){w.valHooks[this]={set:function(e,t){if(Array.isArray(t))return e.checked=w.inArray(w(e).val(),t)>-1}},h.checkOn||(w.valHooks[this].get=function(e){return null===e.getAttribute("value")?"on":e.value})}),h.focusin="onfocusin"in e;var wt=/^(?:focusinfocus|focusoutblur)$/,Tt=function(e){e.stopPropagation()};w.extend(w.event,{trigger:function(t,n,i,o){var a,s,u,l,c,p,d,h,v=[i||r],m=f.call(t,"type")?t.type:t,x=f.call(t,"namespace")?t.namespace.split("."):[];if(s=h=u=i=i||r,3!==i.nodeType&&8!==i.nodeType&&!wt.test(m+w.event.triggered)&&(m.indexOf(".")>-1&&(m=(x=m.split(".")).shift(),x.sort()),c=m.indexOf(":")<0&&"on"+m,t=t[w.expando]?t:new w.Event(m,"object"==typeof t&&t),t.isTrigger=o?2:3,t.namespace=x.join("."),t.rnamespace=t.namespace?new RegExp("(^|\\.)"+x.join("\\.(?:.*\\.|)")+"(\\.|$)"):null,t.result=void 0,t.target||(t.target=i),n=null==n?[t]:w.makeArray(n,[t]),d=w.event.special[m]||{},o||!d.trigger||!1!==d.trigger.apply(i,n))){if(!o&&!d.noBubble&&!y(i)){for(l=d.delegateType||m,wt.test(l+m)||(s=s.parentNode);s;s=s.parentNode)v.push(s),u=s;u===(i.ownerDocument||r)&&v.push(u.defaultView||u.parentWindow||e)}a=0;while((s=v[a++])&&!t.isPropagationStopped())h=s,t.type=a>1?l:d.bindType||m,(p=(J.get(s,"events")||{})[t.type]&&J.get(s,"handle"))&&p.apply(s,n),(p=c&&s[c])&&p.apply&&Y(s)&&(t.result=p.apply(s,n),!1===t.result&&t.preventDefault());return t.type=m,o||t.isDefaultPrevented()||d._default&&!1!==d._default.apply(v.pop(),n)||!Y(i)||c&&g(i[m])&&!y(i)&&((u=i[c])&&(i[c]=null),w.event.triggered=m,t.isPropagationStopped()&&h.addEventListener(m,Tt),i[m](),t.isPropagationStopped()&&h.removeEventListener(m,Tt),w.event.triggered=void 0,u&&(i[c]=u)),t.result}},simulate:function(e,t,n){var r=w.extend(new w.Event,n,{type:e,isSimulated:!0});w.event.trigger(r,null,t)}}),w.fn.extend({trigger:function(e,t){return this.each(function(){w.event.trigger(e,t,this)})},triggerHandler:function(e,t){var n=this[0];if(n)return w.event.trigger(e,t,n,!0)}}),h.focusin||w.each({focus:"focusin",blur:"focusout"},function(e,t){var n=function(e){w.event.simulate(t,e.target,w.event.fix(e))};w.event.special[t]={setup:function(){var r=this.ownerDocument||this,i=J.access(r,t);i||r.addEventListener(e,n,!0),J.access(r,t,(i||0)+1)},teardown:function(){var r=this.ownerDocument||this,i=J.access(r,t)-1;i?J.access(r,t,i):(r.removeEventListener(e,n,!0),J.remove(r,t))}}});var Ct=e.location,Et=Date.now(),kt=/\?/;w.parseXML=function(t){var n;if(!t||"string"!=typeof t)return null;try{n=(new e.DOMParser).parseFromString(t,"text/xml")}catch(e){n=void 0}return n&&!n.getElementsByTagName("parsererror").length||w.error("Invalid XML: "+t),n};var St=/\[\]$/,Dt=/\r?\n/g,Nt=/^(?:submit|button|image|reset|file)$/i,At=/^(?:input|select|textarea|keygen)/i;function jt(e,t,n,r){var i;if(Array.isArray(t))w.each(t,function(t,i){n||St.test(e)?r(e,i):jt(e+"["+("object"==typeof i&&null!=i?t:"")+"]",i,n,r)});else if(n||"object"!==x(t))r(e,t);else for(i in t)jt(e+"["+i+"]",t[i],n,r)}w.param=function(e,t){var n,r=[],i=function(e,t){var n=g(t)?t():t;r[r.length]=encodeURIComponent(e)+"="+encodeURIComponent(null==n?"":n)};if(Array.isArray(e)||e.jquery&&!w.isPlainObject(e))w.each(e,function(){i(this.name,this.value)});else for(n in e)jt(n,e[n],t,i);return r.join("&")},w.fn.extend({serialize:function(){return w.param(this.serializeArray())},serializeArray:function(){return this.map(function(){var e=w.prop(this,"elements");return e?w.makeArray(e):this}).filter(function(){var e=this.type;return this.name&&!w(this).is(":disabled")&&At.test(this.nodeName)&&!Nt.test(e)&&(this.checked||!pe.test(e))}).map(function(e,t){var n=w(this).val();return null==n?null:Array.isArray(n)?w.map(n,function(e){return{name:t.name,value:e.replace(Dt,"\r\n")}}):{name:t.name,value:n.replace(Dt,"\r\n")}}).get()}});var qt=/%20/g,Lt=/#.*$/,Ht=/([?&])_=[^&]*/,Ot=/^(.*?):[ \t]*([^\r\n]*)$/gm,Pt=/^(?:about|app|app-storage|.+-extension|file|res|widget):$/,Mt=/^(?:GET|HEAD)$/,Rt=/^\/\//,It={},Wt={},$t="*/".concat("*"),Bt=r.createElement("a");Bt.href=Ct.href;function Ft(e){return function(t,n){"string"!=typeof t&&(n=t,t="*");var r,i=0,o=t.toLowerCase().match(M)||[];if(g(n))while(r=o[i++])"+"===r[0]?(r=r.slice(1)||"*",(e[r]=e[r]||[]).unshift(n)):(e[r]=e[r]||[]).push(n)}}function _t(e,t,n,r){var i={},o=e===Wt;function a(s){var u;return i[s]=!0,w.each(e[s]||[],function(e,s){var l=s(t,n,r);return"string"!=typeof l||o||i[l]?o?!(u=l):void 0:(t.dataTypes.unshift(l),a(l),!1)}),u}return a(t.dataTypes[0])||!i["*"]&&a("*")}function zt(e,t){var n,r,i=w.ajaxSettings.flatOptions||{};for(n in t)void 0!==t[n]&&((i[n]?e:r||(r={}))[n]=t[n]);return r&&w.extend(!0,e,r),e}function Xt(e,t,n){var r,i,o,a,s=e.contents,u=e.dataTypes;while("*"===u[0])u.shift(),void 0===r&&(r=e.mimeType||t.getResponseHeader("Content-Type"));if(r)for(i in s)if(s[i]&&s[i].test(r)){u.unshift(i);break}if(u[0]in n)o=u[0];else{for(i in n){if(!u[0]||e.converters[i+" "+u[0]]){o=i;break}a||(a=i)}o=o||a}if(o)return o!==u[0]&&u.unshift(o),n[o]}function Ut(e,t,n,r){var i,o,a,s,u,l={},c=e.dataTypes.slice();if(c[1])for(a in e.converters)l[a.toLowerCase()]=e.converters[a];o=c.shift();while(o)if(e.responseFields[o]&&(n[e.responseFields[o]]=t),!u&&r&&e.dataFilter&&(t=e.dataFilter(t,e.dataType)),u=o,o=c.shift())if("*"===o)o=u;else if("*"!==u&&u!==o){if(!(a=l[u+" "+o]||l["* "+o]))for(i in l)if((s=i.split(" "))[1]===o&&(a=l[u+" "+s[0]]||l["* "+s[0]])){!0===a?a=l[i]:!0!==l[i]&&(o=s[0],c.unshift(s[1]));break}if(!0!==a)if(a&&e["throws"])t=a(t);else try{t=a(t)}catch(e){return{state:"parsererror",error:a?e:"No conversion from "+u+" to "+o}}}return{state:"success",data:t}}w.extend({active:0,lastModified:{},etag:{},ajaxSettings:{url:Ct.href,type:"GET",isLocal:Pt.test(Ct.protocol),global:!0,processData:!0,async:!0,contentType:"application/x-www-form-urlencoded; charset=UTF-8",accepts:{"*":$t,text:"text/plain",html:"text/html",xml:"application/xml, text/xml",json:"application/json, text/javascript"},contents:{xml:/\bxml\b/,html:/\bhtml/,json:/\bjson\b/},responseFields:{xml:"responseXML",text:"responseText",json:"responseJSON"},converters:{"* text":String,"text html":!0,"text json":JSON.parse,"text xml":w.parseXML},flatOptions:{url:!0,context:!0}},ajaxSetup:function(e,t){return t?zt(zt(e,w.ajaxSettings),t):zt(w.ajaxSettings,e)},ajaxPrefilter:Ft(It),ajaxTransport:Ft(Wt),ajax:function(t,n){"object"==typeof t&&(n=t,t=void 0),n=n||{};var i,o,a,s,u,l,c,f,p,d,h=w.ajaxSetup({},n),g=h.context||h,y=h.context&&(g.nodeType||g.jquery)?w(g):w.event,v=w.Deferred(),m=w.Callbacks("once memory"),x=h.statusCode||{},b={},T={},C="canceled",E={readyState:0,getResponseHeader:function(e){var t;if(c){if(!s){s={};while(t=Ot.exec(a))s[t[1].toLowerCase()]=t[2]}t=s[e.toLowerCase()]}return null==t?null:t},getAllResponseHeaders:function(){return c?a:null},setRequestHeader:function(e,t){return null==c&&(e=T[e.toLowerCase()]=T[e.toLowerCase()]||e,b[e]=t),this},overrideMimeType:function(e){return null==c&&(h.mimeType=e),this},statusCode:function(e){var t;if(e)if(c)E.always(e[E.status]);else for(t in e)x[t]=[x[t],e[t]];return this},abort:function(e){var t=e||C;return i&&i.abort(t),k(0,t),this}};if(v.promise(E),h.url=((t||h.url||Ct.href)+"").replace(Rt,Ct.protocol+"//"),h.type=n.method||n.type||h.method||h.type,h.dataTypes=(h.dataType||"*").toLowerCase().match(M)||[""],null==h.crossDomain){l=r.createElement("a");try{l.href=h.url,l.href=l.href,h.crossDomain=Bt.protocol+"//"+Bt.host!=l.protocol+"//"+l.host}catch(e){h.crossDomain=!0}}if(h.data&&h.processData&&"string"!=typeof h.data&&(h.data=w.param(h.data,h.traditional)),_t(It,h,n,E),c)return E;(f=w.event&&h.global)&&0==w.active++&&w.event.trigger("ajaxStart"),h.type=h.type.toUpperCase(),h.hasContent=!Mt.test(h.type),o=h.url.replace(Lt,""),h.hasContent?h.data&&h.processData&&0===(h.contentType||"").indexOf("application/x-www-form-urlencoded")&&(h.data=h.data.replace(qt,"+")):(d=h.url.slice(o.length),h.data&&(h.processData||"string"==typeof h.data)&&(o+=(kt.test(o)?"&":"?")+h.data,delete h.data),!1===h.cache&&(o=o.replace(Ht,"$1"),d=(kt.test(o)?"&":"?")+"_="+Et+++d),h.url=o+d),h.ifModified&&(w.lastModified[o]&&E.setRequestHeader("If-Modified-Since",w.lastModified[o]),w.etag[o]&&E.setRequestHeader("If-None-Match",w.etag[o])),(h.data&&h.hasContent&&!1!==h.contentType||n.contentType)&&E.setRequestHeader("Content-Type",h.contentType),E.setRequestHeader("Accept",h.dataTypes[0]&&h.accepts[h.dataTypes[0]]?h.accepts[h.dataTypes[0]]+("*"!==h.dataTypes[0]?", "+$t+"; q=0.01":""):h.accepts["*"]);for(p in h.headers)E.setRequestHeader(p,h.headers[p]);if(h.beforeSend&&(!1===h.beforeSend.call(g,E,h)||c))return E.abort();if(C="abort",m.add(h.complete),E.done(h.success),E.fail(h.error),i=_t(Wt,h,n,E)){if(E.readyState=1,f&&y.trigger("ajaxSend",[E,h]),c)return E;h.async&&h.timeout>0&&(u=e.setTimeout(function(){E.abort("timeout")},h.timeout));try{c=!1,i.send(b,k)}catch(e){if(c)throw e;k(-1,e)}}else k(-1,"No Transport");function k(t,n,r,s){var l,p,d,b,T,C=n;c||(c=!0,u&&e.clearTimeout(u),i=void 0,a=s||"",E.readyState=t>0?4:0,l=t>=200&&t<300||304===t,r&&(b=Xt(h,E,r)),b=Ut(h,b,E,l),l?(h.ifModified&&((T=E.getResponseHeader("Last-Modified"))&&(w.lastModified[o]=T),(T=E.getResponseHeader("etag"))&&(w.etag[o]=T)),204===t||"HEAD"===h.type?C="nocontent":304===t?C="notmodified":(C=b.state,p=b.data,l=!(d=b.error))):(d=C,!t&&C||(C="error",t<0&&(t=0))),E.status=t,E.statusText=(n||C)+"",l?v.resolveWith(g,[p,C,E]):v.rejectWith(g,[E,C,d]),E.statusCode(x),x=void 0,f&&y.trigger(l?"ajaxSuccess":"ajaxError",[E,h,l?p:d]),m.fireWith(g,[E,C]),f&&(y.trigger("ajaxComplete",[E,h]),--w.active||w.event.trigger("ajaxStop")))}return E},getJSON:function(e,t,n){return w.get(e,t,n,"json")},getScript:function(e,t){return w.get(e,void 0,t,"script")}}),w.each(["get","post"],function(e,t){w[t]=function(e,n,r,i){return g(n)&&(i=i||r,r=n,n=void 0),w.ajax(w.extend({url:e,type:t,dataType:i,data:n,success:r},w.isPlainObject(e)&&e))}}),w._evalUrl=function(e){return w.ajax({url:e,type:"GET",dataType:"script",cache:!0,async:!1,global:!1,"throws":!0})},w.fn.extend({wrapAll:function(e){var t;return this[0]&&(g(e)&&(e=e.call(this[0])),t=w(e,this[0].ownerDocument).eq(0).clone(!0),this[0].parentNode&&t.insertBefore(this[0]),t.map(function(){var e=this;while(e.firstElementChild)e=e.firstElementChild;return e}).append(this)),this},wrapInner:function(e){return g(e)?this.each(function(t){w(this).wrapInner(e.call(this,t))}):this.each(function(){var t=w(this),n=t.contents();n.length?n.wrapAll(e):t.append(e)})},wrap:function(e){var t=g(e);return this.each(function(n){w(this).wrapAll(t?e.call(this,n):e)})},unwrap:function(e){return this.parent(e).not("body").each(function(){w(this).replaceWith(this.childNodes)}),this}}),w.expr.pseudos.hidden=function(e){return!w.expr.pseudos.visible(e)},w.expr.pseudos.visible=function(e){return!!(e.offsetWidth||e.offsetHeight||e.getClientRects().length)},w.ajaxSettings.xhr=function(){try{return new e.XMLHttpRequest}catch(e){}};var Vt={0:200,1223:204},Gt=w.ajaxSettings.xhr();h.cors=!!Gt&&"withCredentials"in Gt,h.ajax=Gt=!!Gt,w.ajaxTransport(function(t){var n,r;if(h.cors||Gt&&!t.crossDomain)return{send:function(i,o){var a,s=t.xhr();if(s.open(t.type,t.url,t.async,t.username,t.password),t.xhrFields)for(a in t.xhrFields)s[a]=t.xhrFields[a];t.mimeType&&s.overrideMimeType&&s.overrideMimeType(t.mimeType),t.crossDomain||i["X-Requested-With"]||(i["X-Requested-With"]="XMLHttpRequest");for(a in i)s.setRequestHeader(a,i[a]);n=function(e){return function(){n&&(n=r=s.onload=s.onerror=s.onabort=s.ontimeout=s.onreadystatechange=null,"abort"===e?s.abort():"error"===e?"number"!=typeof s.status?o(0,"error"):o(s.status,s.statusText):o(Vt[s.status]||s.status,s.statusText,"text"!==(s.responseType||"text")||"string"!=typeof s.responseText?{binary:s.response}:{text:s.responseText},s.getAllResponseHeaders()))}},s.onload=n(),r=s.onerror=s.ontimeout=n("error"),void 0!==s.onabort?s.onabort=r:s.onreadystatechange=function(){4===s.readyState&&e.setTimeout(function(){n&&r()})},n=n("abort");try{s.send(t.hasContent&&t.data||null)}catch(e){if(n)throw e}},abort:function(){n&&n()}}}),w.ajaxPrefilter(function(e){e.crossDomain&&(e.contents.script=!1)}),w.ajaxSetup({accepts:{script:"text/javascript, application/javascript, application/ecmascript, application/x-ecmascript"},contents:{script:/\b(?:java|ecma)script\b/},converters:{"text script":function(e){return w.globalEval(e),e}}}),w.ajaxPrefilter("script",function(e){void 0===e.cache&&(e.cache=!1),e.crossDomain&&(e.type="GET")}),w.ajaxTransport("script",function(e){if(e.crossDomain){var t,n;return{send:function(i,o){t=w(" + + + + + + +

PHP CloudPRNT Queue Sample

+ +

Registered CloudPRNT Devices

+ +
+ +

Queues

+
+ +

Device Configuration

+

To connect a new device, please set its CloudPRNT URL to:
+

...

+ then use the "Register A New Device" option to enable your device with this server. +

+ + diff --git a/ExampleServers/php_queue/print.html b/ExampleServers/php_queue/print.html new file mode 100644 index 0000000..7e81939 --- /dev/null +++ b/ExampleServers/php_queue/print.html @@ -0,0 +1,27 @@ + + + + Print a ticket + + + + + + + + +

Please take a ticket

+
+ Print +
+ + + diff --git a/ExampleServers/php_queue/print.php b/ExampleServers/php_queue/print.php new file mode 100755 index 0000000..32891b8 --- /dev/null +++ b/ExampleServers/php_queue/print.php @@ -0,0 +1,95 @@ +query("SELECT position FROM Queues WHERE id = '".$queue."'"); + if (isset($results)) { + $row = $results->fetchArray(); // fetch next row + + if (isset($row) && !empty($row)) { + $pos = intval($row['position']); + + $updateposition = $db->query("UPDATE Queues SET position = position + 1 WHERE id = '".$queue."'"); + + if (empty($updateposition)) + { + http_response_code(500); + return; + } + + $updateprinting = $db->query("UPDATE Devices SET 'Printing' = '".$pos."' WHERE DeviceMac = '" .$mac."'"); + + if (empty($updateprinting)) + { + // error message + http_response_code(500); + return; + } + + } + + print_r($pos); + } + + return; +} + +function getQueueIDAndPrintingState($db, $mac) { + $results = $db->query("SELECT QueueID, Printing FROM Devices WHERE DeviceMac = '".$mac."'"); + + if (isset($results)) { + $row = $results->fetchArray(); // fetch next row + + if (isset($row) && !empty($row)) { + return array($row['QueueID'], $row['Printing']); + } + + } + + return array(NULL, NULL); +} + +function handleGETRequest() { + $dbname = "simplequeue.sqlite"; // database file name + $db = new SQLite3($dbname); + + if (!empty($_GET['mac'])) { + $mac = $_GET['mac']; + } + + if (!isset($db) || empty($db)) { + http_response_code(500); + return; + } + + if (!isset($mac) || empty($mac)) { + http_response_code(400); // no "mac" parameter(Bad Request) + return; + } + + list($queue, $printing) = getQueueIDAndPrintingState($db, $mac); + + if (!isset($queue)) + { + http_response_code(400); + return; // Can't print a ticket if there is no queue assigned to this printer + } + + if ((isset($printing)) && ($printing > 0)) + { + http_response_code(200); + return; // Don't issue a ticket if one is currently printing + } + + $pos = triggerPrint($db, $mac, $queue); + + $db->close(); +} + +if ($_SERVER['REQUEST_METHOD'] === "GET") { + handleGETRequest(); +} else { + http_response_code(405); +} +?> diff --git a/ExampleServers/php_queue/queues.php b/ExampleServers/php_queue/queues.php new file mode 100755 index 0000000..fa4ff18 --- /dev/null +++ b/ExampleServers/php_queue/queues.php @@ -0,0 +1,86 @@ +query("INSERT INTO `Queues`(name) VALUES ('".$name."');"); + + if (!isset($affected)) { + http_response_code(500); + } +} + +function delQueue($db, $id) { + $affected = $db->query("DELETE FROM `Queues` WHERE `id`='".$id."';"); + + if (!isset($affected)) { + http_response_code(500); + } +} + +function resetQueue($db, $id) { + $affected = $db->query("UPDATE Queues SET 'position' = 1 WHERE `id`='".$id."';"); + + if (!isset($affected)) { + http_response_code(500); + } +} + +function listQueues($db) { + $results = $db->query("SELECT id, name, position FROM Queues"); + $rdata = array(); + $count = 0; + + if (isset($results)) { + while ($row = $results->fetchArray()) { + $rdata[$count] = array("id" => strval($row['id'])); + $rdata[$count] += array("name" => $row['name']); + $rdata[$count] += array("nextPos" => strval($row['position'])); + $count++; + } + + header("Content-Type: application/json"); + print_r(json_encode($rdata)); + } else { + http_response_code(500); + } +} + +function handleGETRequest() { + $dbname = "simplequeue.sqlite"; // database file name + $db = new SQLite3($dbname); + if (!empty($_GET['new'])) { + $new = $_GET['new']; + } + + if (!empty($_GET['del'])) { + $del = $_GET['del']; + } + + if (!empty($_GET['reset'])) { + $reset = $_GET['reset']; + } + + if (!isset($db) || empty($db)) { + http_response_code(500); + return; + } + + if (isset($new)) { + addQueue($db, $new); + } elseif (isset($del)) { + delQueue($db, $del); + } elseif (isset($reset)) { + resetQueue($db, $reset); + } else { + listQueues($db); + } + + $db->close(); +} + +if ($_SERVER['REQUEST_METHOD'] === "GET") { + handleGETRequest(); +} else { + http_response_code(405); +} +?> diff --git a/ExampleServers/php_queue/simplequeue.sqlite b/ExampleServers/php_queue/simplequeue.sqlite new file mode 100755 index 0000000000000000000000000000000000000000..d9129f9b0087e3f4e2b126f5bf26a46dab8a29ca GIT binary patch literal 11264 zcmeHNPfr_16rVp}yc==I0a+H82~|WW7-P~@l{vHqwh^kKK4hL&hBhn zpCTvy61hjc^b54Net_Jn9CGfh;?P{uLwo3qcL}Ouq$WZXqS@8+?3;P}-kaa-d)`0q z)>hS%jNB8UPbIkyMgWB13qk;F{s;iLq{vc)6>TaSQFOGyqk|J$t)uYjr%@#U@n2f( zQqr7wh8Zvj7zEA?0efy-*+S?kz*o^z^c(#7%uE|Y=M90rjj|vQr@N29ipyBUtUDs) zEs`)%&85M8(i5@%vmjmSNiS&6kuD=$k8^UMTj>r29--R~FS&wJ? z5R9)gDx+P>y>?J0O*ID=?(KR$ZL>0oLr&g%%1a8smO}8;g{w=%_ku#ge)5^`@7cS` zK$&#O;u3Mm;@&s5c7v>lSlhREL>!VJ_79j^nRGRplylZ1kt;&Udvin%Tfcc*$3K1z z@Zb0~{saGh-Y!bxk3qm7aM}orVh9n!*s_xNKLq#?|Ec%Wwq*1f1PlV_0|6W7VRAEv zvN&fAZe+%BT|JvG1H6oX!QT1s(|BPJxHt%0#@56{cHnOibFN7-`sLY0*lhel#s71F zpX>c1cx-$$2p9y0A&|urP^TaLvVL}$fax;`7z7Lg1_6VBLBJqzi~v%H`Wa?Sk^Wq- z$!rDzgTM!lfd2lEQ4gSB(GRLQgwIe0Wj^ppU%ctPcn6o!191Hv#Lr%I@Um?7qfGAe zJOp0QV&6p%xT-?ir?C_Ret#=wF^l#WlXhfw>OTmV5@G!K<11sid>(#Zl=OhJq&N9R zE89+`=8#%tx$2Oqq;rZ~v#o~LYFKLbYc0{DgAw)1l#j5jVrCzO(lGfrf+G1g%NAvfDP@nIQd0qXGS~)sz`n~H3rnQBp zh&$RZ?YZJNx7XGy+dJedXXl#Nnz3h+`k$8oXVFXKBKPdC24m46aM}pm0HCmx$yFv# z$}g+zq1RLirj#CJ`f+(IH#rHPR0c^S?M|D~f2WPKH_00bvre07+z!bOgEX_Y`gU^A z0lF&W9bNWwJbD!Q3wrpLq%w})#BXDTd#dE9*6XC%NXsOBw^ Documents) + +# 2. Contents + +~~~ +php_queue_v100 +|- Readme_En.txt // Release Notes (English) +|- Readme_Jp.txt // Release Notes (Japanese) +|- SoftwareLicenseAgreement.pdf // Software License Agreement (English) +|- SoftwareLicenseAgreement_Jp.pdf // Software License Agreement (Japanese) +| ++- php_queue + |- cloudprnt.php // Sample CloudPRNT Queue system handler including a using of cputil + |- cpphp.css // Style sheet for mangament.html / print.html + |- devices.php // Sample for querying the database, managing queue of device information + |- management.html // Management page for regsiter/query printer and queue for print job + |- print.html // Simple print button web page for registered device + |- print.php // Sample for querying the database, configuring and triggering jobs + |- queues.php // Sample for querying the database, managing queue of job data information + |- simplequeue.sqlite // Database file used by cloudprnt.php devices.php / print.php / queues.php + +- js + |- jquery-3.3.1.min.js // jquery 3.3.1 JavaScript library + +- management.js // JavaScript for updating a information of management.html +~~~ + +# 3. Scope + +Please refer to the StarPRNT SDK document about the supported printers. + +Works with these CloudPRNT client printers: + +- mC-Print2 +- mC-Print3 +- TSP650II with IFBD-HI01X +- TSP700II with IFBD-HI01X +- TSP800II with IFBD-HI01X +- SP700 with IFBD-HI02X + +Please refer to each CloudPRNT client printer for details. +You can download the manual from Star web site. + +# 4. Usage + +This example project can be work after hosting by server including PHP and SQLite library. + +It can be test by access to ```http():///management.html``` + +Please refer to SDK documents for details. +(http://www.starmicronics.com/support/SDKDocumentation.aspx - CloudPRNT -> Documents) + + +# 5. Copyright + +Copyright 2019 Star Micronics Co., Ltd. All rights reserved. + + +# 6. Release History + +- Ver.1.0.0 (2019/11/05) + + First release. diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..ad01769 --- /dev/null +++ b/LICENSE @@ -0,0 +1,35 @@ +Software License Agreement + +This Agreement made and entered into by and between you and Star Micronics Co., Ltd. (hereinafter referred to as "Star") stipulates the terms and conditions pertaining to the licensing of the software. Please read this Software License Agreement ("Agreement") carefully before installing or using the software and accompanying data (hereinafter referred to as "the Software"). By installing the Software, you are agreeing to be bound by this Agreement. If you do not agree to the terms of this Agreement, you are not entitled to install the Software. References to "Software" in this Agreement include any accompanying documentation furnished by Star. + +1. Permitted License Uses +During the term of this Agreement, Star grants to you a nonexclusive, non-transferable license to use the Software for your own use subject to the terms and conditions of this Agreement. Except for this limited license, Star reserves all other rights in the Software. The rights granted herein are limited to Star's intellectual property rights in the Software. Only for the purpose of using a Star product, you may install the Software on a computer that is directly or via a local area network connected to the Star product. + +2. Restrictions on Permitted License Uses +You may not reverse engineer, disassemble, or decompile with regard to the Software or otherwise attempt to discover the trade secrets in the Software. In addition, you may not copy, reproduce, alter, modify or create derivative works of the Software or any part thereof. Notwithstanding the provision above, you may analyze, copy, or alter the binary data (object code) of the part of source code disclosed out of the Software. You may not sublicense, transfer, rent, lease, or redistribute the Software to a third party. Star is not obligated to provide any maintenance, technical or other support for the Software. You may use the Software only with a Star product and you are not permitted to use the Software for any product other than a Star product. + +3. Intellectual Property Rights +Copyrights, patents and any other intellectual property rights in the Software shall belong to Star or Star's licensors. This is a license, not a sale. + +4. Termination +This Agreement is effective until terminated. Your rights under this Agreement will terminate automatically without notice from Star if you fail to comply with any term(s) of this Agreement. Upon the termination of this Agreement, you shall cease all use of the Software and destroy all copies, full or partial, of the Software. + +5. Disclaimer of Warranties +You expressly acknowledge and agree that use of the Software is at your sole risk and that the entire risk as to satisfactory quality, performance, accuracy and efforts is with you. The Software is provided "as is", with all faults and without warranty of any kind, and Star and Star's licensors hereby disclaim all warranties and conditions with respect to the Software, either express, implied or statutory, including, but not limited to, the implied warranties and/or conditions of merchantability, of satisfactory quality, of fitness for a particular purpose, of accuracy, of quiet enjoyment, and non-infringement of third party rights. Star does not warrant against interference with your enjoyment of the Software, that the functions contained in the Software will meet your requirements, that the operation of the Software will be uninterrupted or error-free, or that defects in the Software will be corrected. No oral or written information or advice given by Star or Star authorized representative shall create a warranty. Should the Software prove defective, you assume the entire cost of all necessary servicing, repair, or correction. + +6. Limitation of Liability +To the extent not prohibited by law, in no event shall Star be liable for personal injury, or any incidental, special, indirect or consequential damages whatsoever, including, without limitation, damages for loss of profits, loss of data, business interruption or any other commercial damages or losses, arising out of or related to your use or inability to use the Software, however caused, regardless of the theory of liability (contract, tort, or otherwise) and even if Star has been advised of the possibility of such damages. In any event, Star shall not be liable for any damages, in the aggregate, regardless of type or kind, whether in contract or tort, in excess of the actual license fees, if any, paid by you for the Software in the three (3) months immediately preceding the first event giving rise to liability. + +7. Governing Law and Severability +This Agreement will be governed by and construed in accordance with the laws of Japan. If for any reason a court of competent jurisdiction finds any provision, or portion thereof, to be unenforceable, the remainder of this Agreement shall continue in full force and effect. + +8. Third-party Software +If the whole or part of the Software includes any third-party software or intellectual property right including, but not limited to, open source software (hereinafter referred to as the "Third-party Software"), you shall comply with the terms and conditions of the license granted by the third party related to your use of the Third-party Software. In no event shall any of the provisions of this Agreement be construed as a limitation on the right of the third party to enforce each and every terms and conditions of the license. In no event shall Star be liable for any limitation on the use of the Software, which might be imposed by enforcement of the license by the third party. If the Software includes the Third-party Software, you will find the particulars thereof including the licensing conditions in the "SoftwareLicenseAgreementAppendix.pdf". All Third-party Software is provided as-is, with all faults and without warranties of any kind. + +9. Compensation for damages +If you fail to comply with any term of this Agreement, Star has the right to terminate this Agreement and any other agreement made with you and claim compensation for damages suffered resulting from such termination. + +10. Amendment and Alteration +You should be aware that we may change this Agreement at any time. In the event of a change, we will inform you of the change and changed version of this Agreement by displaying it on StarÅfs website or by other appropriate means. Unless otherwise specified, the changed version of this Agreement shall become effective when displayed on StarÅfs website. +To read our latest Software License Agreement, please visit the following URL. +https://www.star-m.jp/wp-content/uploads/SoftwareLicenseAgreement_web.pdf