diff --git a/android-icon-144x144.png b/android-icon-144x144.png
new file mode 100755
index 0000000..02bdff9
Binary files /dev/null and b/android-icon-144x144.png differ
diff --git a/android-icon-192x192.png b/android-icon-192x192.png
new file mode 100755
index 0000000..5bd7090
Binary files /dev/null and b/android-icon-192x192.png differ
diff --git a/android-icon-36x36.png b/android-icon-36x36.png
new file mode 100755
index 0000000..d5ba23d
Binary files /dev/null and b/android-icon-36x36.png differ
diff --git a/android-icon-48x48.png b/android-icon-48x48.png
new file mode 100755
index 0000000..5454c81
Binary files /dev/null and b/android-icon-48x48.png differ
diff --git a/android-icon-72x72.png b/android-icon-72x72.png
new file mode 100755
index 0000000..2817881
Binary files /dev/null and b/android-icon-72x72.png differ
diff --git a/android-icon-96x96.png b/android-icon-96x96.png
new file mode 100755
index 0000000..f45e0e7
Binary files /dev/null and b/android-icon-96x96.png differ
diff --git a/apple-icon-114x114.png b/apple-icon-114x114.png
new file mode 100755
index 0000000..45a994c
Binary files /dev/null and b/apple-icon-114x114.png differ
diff --git a/apple-icon-120x120.png b/apple-icon-120x120.png
new file mode 100755
index 0000000..09fa7af
Binary files /dev/null and b/apple-icon-120x120.png differ
diff --git a/apple-icon-144x144.png b/apple-icon-144x144.png
new file mode 100755
index 0000000..02bdff9
Binary files /dev/null and b/apple-icon-144x144.png differ
diff --git a/apple-icon-152x152.png b/apple-icon-152x152.png
new file mode 100755
index 0000000..7a3e1d0
Binary files /dev/null and b/apple-icon-152x152.png differ
diff --git a/apple-icon-180x180.png b/apple-icon-180x180.png
new file mode 100755
index 0000000..803f3b1
Binary files /dev/null and b/apple-icon-180x180.png differ
diff --git a/apple-icon-57x57.png b/apple-icon-57x57.png
new file mode 100755
index 0000000..0407331
Binary files /dev/null and b/apple-icon-57x57.png differ
diff --git a/apple-icon-60x60.png b/apple-icon-60x60.png
new file mode 100755
index 0000000..16b4fc6
Binary files /dev/null and b/apple-icon-60x60.png differ
diff --git a/apple-icon-72x72.png b/apple-icon-72x72.png
new file mode 100755
index 0000000..2817881
Binary files /dev/null and b/apple-icon-72x72.png differ
diff --git a/apple-icon-76x76.png b/apple-icon-76x76.png
new file mode 100755
index 0000000..641d5d4
Binary files /dev/null and b/apple-icon-76x76.png differ
diff --git a/apple-icon-precomposed.png b/apple-icon-precomposed.png
new file mode 100755
index 0000000..ce491cd
Binary files /dev/null and b/apple-icon-precomposed.png differ
diff --git a/apple-icon.png b/apple-icon.png
new file mode 100755
index 0000000..ce491cd
Binary files /dev/null and b/apple-icon.png differ
diff --git a/browserconfig.xml b/browserconfig.xml
new file mode 100755
index 0000000..c554148
--- /dev/null
+++ b/browserconfig.xml
@@ -0,0 +1,2 @@
+
+#ffffff
\ No newline at end of file
diff --git a/favicon-16x16.png b/favicon-16x16.png
new file mode 100755
index 0000000..f2d03dc
Binary files /dev/null and b/favicon-16x16.png differ
diff --git a/favicon-32x32.png b/favicon-32x32.png
new file mode 100755
index 0000000..f4b1722
Binary files /dev/null and b/favicon-32x32.png differ
diff --git a/favicon-96x96.png b/favicon-96x96.png
new file mode 100755
index 0000000..f45e0e7
Binary files /dev/null and b/favicon-96x96.png differ
diff --git a/favicon.ico b/favicon.ico
new file mode 100755
index 0000000..fb0555b
Binary files /dev/null and b/favicon.ico differ
diff --git a/manifest.json b/manifest.json
new file mode 100755
index 0000000..013d4a6
--- /dev/null
+++ b/manifest.json
@@ -0,0 +1,41 @@
+{
+ "name": "App",
+ "icons": [
+ {
+ "src": "\/android-icon-36x36.png",
+ "sizes": "36x36",
+ "type": "image\/png",
+ "density": "0.75"
+ },
+ {
+ "src": "\/android-icon-48x48.png",
+ "sizes": "48x48",
+ "type": "image\/png",
+ "density": "1.0"
+ },
+ {
+ "src": "\/android-icon-72x72.png",
+ "sizes": "72x72",
+ "type": "image\/png",
+ "density": "1.5"
+ },
+ {
+ "src": "\/android-icon-96x96.png",
+ "sizes": "96x96",
+ "type": "image\/png",
+ "density": "2.0"
+ },
+ {
+ "src": "\/android-icon-144x144.png",
+ "sizes": "144x144",
+ "type": "image\/png",
+ "density": "3.0"
+ },
+ {
+ "src": "\/android-icon-192x192.png",
+ "sizes": "192x192",
+ "type": "image\/png",
+ "density": "4.0"
+ }
+ ]
+}
\ No newline at end of file
diff --git a/ms-icon-144x144.png b/ms-icon-144x144.png
new file mode 100755
index 0000000..02bdff9
Binary files /dev/null and b/ms-icon-144x144.png differ
diff --git a/ms-icon-150x150.png b/ms-icon-150x150.png
new file mode 100755
index 0000000..087a77f
Binary files /dev/null and b/ms-icon-150x150.png differ
diff --git a/ms-icon-310x310.png b/ms-icon-310x310.png
new file mode 100755
index 0000000..342e096
Binary files /dev/null and b/ms-icon-310x310.png differ
diff --git a/ms-icon-70x70.png b/ms-icon-70x70.png
new file mode 100755
index 0000000..09ed5a7
Binary files /dev/null and b/ms-icon-70x70.png differ
diff --git a/procentric/application/.vscode/bookmarks.json b/procentric/application/.vscode/bookmarks.json
new file mode 100755
index 0000000..dc1d30f
--- /dev/null
+++ b/procentric/application/.vscode/bookmarks.json
@@ -0,0 +1,14 @@
+{
+ "files": [
+ {
+ "path": "lib/hoteltv.ui_appfull.js",
+ "bookmarks": [
+ {
+ "line": 3332,
+ "column": 13,
+ "label": ""
+ }
+ ]
+ }
+ ]
+}
\ No newline at end of file
diff --git a/procentric/application/app_hoteltv_full.html b/procentric/application/app_hoteltv_full.html
new file mode 100755
index 0000000..eaca156
--- /dev/null
+++ b/procentric/application/app_hoteltv_full.html
@@ -0,0 +1,460 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ CENTIRM LG-PROCENTRIC HOTEL SERVICE
+
+
+
+
+
+
+
+
+
+
+
Seoul
+
+
+
+
+
+ -
+
+
+
+ -
+
+
+
+ -
+
+
+
+ -
+
+
+
+ -
+
+
+
+
+
+
+
+ -
+
+
+
+ -
+
+
+
+ -
+
+
+
+ -
+
+
+
+ -
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/procentric/application/css/acmeticker/style.css b/procentric/application/css/acmeticker/style.css
new file mode 100755
index 0000000..94f6e1a
--- /dev/null
+++ b/procentric/application/css/acmeticker/style.css
@@ -0,0 +1,129 @@
+* {
+ margin: 0;
+ padding: 0; }
+
+*,
+::after,
+::before {
+ -webkit-box-sizing: border-box;
+ box-sizing: border-box; }
+
+a {
+ text-decoration: none;
+ -webkit-transition: all 0.5s ease-in-out 0s;
+ -o-transition: all 0.5s ease-in-out 0s;
+ transition: all 0.5s ease-in-out 0s; }
+ a:hover {
+ text-decoration: none; }
+
+/*-----------------------------
+ News Ticker
+------------------------------*/
+.acme-news-ticker {
+ background: #fff;
+ position: relative;
+ height: 45px;
+ border: 1px solid #1974d2;
+ margin-top: 45px; }
+ @media (min-width: 768px) {
+ .acme-news-ticker {
+ margin-top: 0; } }
+ .acme-news-ticker-label {
+ background: #1974d2;
+ padding: 10px;
+ width: auto;
+ float: left;
+ margin-right: 15px;
+ line-height: normal;
+ height: 100%;
+ color: #fff; }
+ @media (max-width: 575px) {
+ .acme-news-ticker-label {
+ position: absolute;
+ top: -45px; } }
+ .acme-news-ticker-box {
+ height: 100%;
+ padding-top: 10px;
+ overflow: hidden; }
+ @media (max-width: 575px) {
+ .acme-news-ticker-box {
+ padding-left: 10px;
+ padding-right: 120px; } }
+ .acme-news-ticker-box ul {
+ width: 100%;
+ list-style-type: none !important;
+ padding: 0;
+ margin: 0; }
+ .acme-news-ticker-box ul li a {
+ text-decoration: none; }
+ .acme-news-ticker-controls {
+ display: -webkit-box;
+ display: -ms-flexbox;
+ display: flex;
+ position: absolute;
+ height: 100%;
+ right: 0;
+ top: 0; }
+ .acme-news-ticker-controls button {
+ height: 100%;
+ background: #f6f6f6;
+ padding: 0;
+ width: 40px;
+ border-color: #eeeeee;
+ border-style: solid;
+ border-width: 0 0 0 1px;
+ cursor: pointer;
+ display: inline-block; }
+ .acme-news-ticker-controls button:hover {
+ background: #eeeeee; }
+ .acme-news-ticker-controls button.acme-news-ticker-arrow {
+ margin: 0;
+ display: inline-block;
+ position: relative; }
+ .acme-news-ticker-controls button.acme-news-ticker-arrow:after {
+ border-color: #999;
+ border-bottom-style: solid;
+ border-bottom-width: 2px;
+ border-right-style: solid;
+ border-right-width: 2px;
+ content: '';
+ display: inline-block;
+ height: 8px;
+ left: 50%;
+ position: absolute;
+ top: 50%;
+ width: 8px; }
+ .acme-news-ticker-controls button.acme-news-ticker-pause {
+ position: relative;
+ display: inline-block; }
+ .acme-news-ticker-controls button.acme-news-ticker-pause:before {
+ position: absolute;
+ content: "";
+ width: 10px;
+ height: 10px;
+ border-color: #999;
+ border-style: solid;
+ border-width: 0 2px 0;
+ -webkit-transform: translate(-50%, -50%);
+ -ms-transform: translate(-50%, -50%);
+ transform: translate(-50%, -50%);
+ left: 50%;
+ top: 50%; }
+ .acme-news-ticker-controls.acme-news-ticker-horizontal-controls button.acme-news-ticker-prev:after {
+ -webkit-transform: translate(-50%, -50%) rotate(135deg);
+ -ms-transform: translate(-50%, -50%) rotate(135deg);
+ transform: translate(-50%, -50%) rotate(135deg); }
+ .acme-news-ticker-controls.acme-news-ticker-horizontal-controls button.acme-news-ticker-next:after {
+ -webkit-transform: translate(-50%, -50%) rotate(315deg);
+ -ms-transform: translate(-50%, -50%) rotate(315deg);
+ transform: translate(-50%, -50%) rotate(315deg); }
+ .acme-news-ticker-controls.acme-news-ticker-vertical-controls button.acme-news-ticker-prev:after {
+ -webkit-transform: translate(-50%, -50%) rotate(225deg);
+ -ms-transform: translate(-50%, -50%) rotate(225deg);
+ transform: translate(-50%, -50%) rotate(225deg); }
+ .acme-news-ticker-controls.acme-news-ticker-vertical-controls button.acme-news-ticker-next:after {
+ -webkit-transform: translate(-50%, -50%) rotate(405deg);
+ -ms-transform: translate(-50%, -50%) rotate(405deg);
+ transform: translate(-50%, -50%) rotate(405deg); }
+
+/*# sourceMappingURL=style.css.map */
\ No newline at end of file
diff --git a/procentric/application/css/acmeticker/style.css.map b/procentric/application/css/acmeticker/style.css.map
new file mode 100755
index 0000000..2d8526c
--- /dev/null
+++ b/procentric/application/css/acmeticker/style.css.map
@@ -0,0 +1 @@
+{"version":3,"sources":["../scss/main.scss","../scss/base/_mixins.scss","../scss/base/_variable.scss"],"names":[],"mappings":"AAEA;EACC,UAAS;EACT,WAAU,EAAA;;AAEX;;;EAGG,+BAAsB;UAAtB,uBAAsB,EAAA;;AAGzB;EACC,sBAAoB;EACpB,4CAAkC;EAAlC,uCAAkC;EAAlC,oCAAkC,EAAA;EAClC;IACC,sBAAoB,EAAA;;AAKtB;;gCAEgC;AAChC;EAEI,iBAAgB;EAChB,mBAAkB;EAClB,aAAY;EACZ,0BAAgC;EAChC,iBAAgB,EAAA;ECiKhB;IDvKJ;MASQ,cAAa,EAAA,EAAA;EAEjB;IACI,oBED+B;IFE/B,cAAa;IACb,YAAW;IACX,YAAW;IACX,mBAAkB;IAClB,oBAAmB;IACnB,aAAY;IACZ,YAAW,EAAA;IC+Kf;MDvLA;QAWQ,mBAAkB;QAClB,WAAU,EAAA,EAAA;EAGlB;IACI,aAAY;IACZ,kBAAiB;IACjB,iBAAgB,EAAA;ICqKpB;MDxKA;QAKQ,mBAAkB;QAClB,qBAAoB,EAAA,EAAA;IAExB;MACI,YAAW;MACX,iCAAgC;MAChC,WAAU;MACV,UAAS,EAAA;MAEL;QACI,sBAAqB,EAAA;EAKrC;IAEI,qBAAa;IAAb,qBAAa;IAAb,cAAa;IAGb,mBAAkB;IAClB,aAAY;IACZ,SAAQ;IACR,OAAM,EAAA;IACN;MACI,aAAY;MACZ,oBAAkB;MAClB,WAAU;MACV,YAAW;MACX,sBE/DuC;MFgEvC,oBAAmB;MACnB,wBAAuB;MACvB,gBAAe;MACf,sBAAqB,EAAA;MACrB;QACI,oBErEmC,EAAA;MFuEvC;QACI,UAAS;QACT,sBAAqB;QACrB,mBAAkB,EAAA;QACd;UACI,mBAAkB;UAClB,2BAA0B;UAC1B,yBAAwB;UACxB,0BAAyB;UACzB,wBAAuB;UACvB,YAAW;UACX,sBAAqB;UACrB,YAAW;UACX,UAAS;UACT,mBAAkB;UAClB,SAAQ;UACR,WAAU,EAAA;MAKtB;QACI,mBAAkB;QAClB,sBAAqB,EAAA;QACrB;UACI,mBAAkB;UAClB,YAAW;UACX,YAAW;UACX,aAAY;UACZ,mBAAkB;UAClB,oBAAmB;UACnB,sBAAqB;UACrB,yCAAgC;cAAhC,qCAAgC;kBAAhC,iCAAgC;UAChC,UAAS;UACT,SAAQ,EAAA;IAUR;MACG,wDAA6C;UAA7C,oDAA6C;cAA7C,gDAA6C,EAAA;IAKhD;MACI,wDAA8C;UAA9C,oDAA8C;cAA9C,gDAA8C,EAAA;IAU9C;MAEI,wDAA8C;UAA9C,oDAA8C;cAA9C,gDAA8C,EAAA;IAKlD;MAEI,wDAA8C;UAA9C,oDAA8C;cAA9C,gDAA8C,EAAA","file":"style.css"}
\ No newline at end of file
diff --git a/procentric/application/css/acmeticker/style.min.css b/procentric/application/css/acmeticker/style.min.css
new file mode 100755
index 0000000..bf49725
--- /dev/null
+++ b/procentric/application/css/acmeticker/style.min.css
@@ -0,0 +1 @@
+*{margin:0;padding:0}*,::after,::before{box-sizing:border-box}a{text-decoration:none;transition:all .5s ease-in-out 0s}a:hover{text-decoration:none}.acme-news-ticker{background:#fff;position:relative;height:45px;border:1px solid #1974d2;margin-top:45px}@media (min-width:768px){.acme-news-ticker{margin-top:0}}.acme-news-ticker-label{background:#1974d2;padding:10px;width:auto;float:left;margin-right:15px;line-height:normal;height:100%;color:#fff}@media (max-width:575px){.acme-news-ticker-label{position:absolute;top:-45px}}.acme-news-ticker-box{height:100%;padding-top:10px;overflow:hidden}@media (max-width:575px){.acme-news-ticker-box{padding-left:10px;padding-right:120px}}.acme-news-ticker-box ul{width:100%;list-style-type:none!important;padding:0;margin:0}.acme-news-ticker-box ul li a{text-decoration:none}.acme-news-ticker-controls{display:flex;position:absolute;height:100%;right:0;top:0}.acme-news-ticker-controls button{height:100%;background:#f6f6f6;padding:0;width:40px;border-color:#eee;border-style:solid;border-width:0 0 0 1px;cursor:pointer;display:inline-block}.acme-news-ticker-controls button:hover{background:#eee}.acme-news-ticker-controls button.acme-news-ticker-arrow{margin:0;display:inline-block;position:relative}.acme-news-ticker-controls button.acme-news-ticker-arrow:after{border-color:#999;border-bottom-style:solid;border-bottom-width:2px;border-right-style:solid;border-right-width:2px;content:'';display:inline-block;height:8px;left:50%;position:absolute;top:50%;width:8px}.acme-news-ticker-controls button.acme-news-ticker-pause{position:relative;display:inline-block}.acme-news-ticker-controls button.acme-news-ticker-pause:before{position:absolute;content:"";width:10px;height:10px;border-color:#999;border-style:solid;border-width:0 2px 0;transform:translate(-50%,-50%);left:50%;top:50%}.acme-news-ticker-controls.acme-news-ticker-horizontal-controls button.acme-news-ticker-prev:after{transform:translate(-50%,-50%) rotate(135deg)}.acme-news-ticker-controls.acme-news-ticker-horizontal-controls button.acme-news-ticker-next:after{transform:translate(-50%,-50%) rotate(315deg)}.acme-news-ticker-controls.acme-news-ticker-vertical-controls button.acme-news-ticker-prev:after{transform:translate(-50%,-50%) rotate(225deg)}.acme-news-ticker-controls.acme-news-ticker-vertical-controls button.acme-news-ticker-next:after{transform:translate(-50%,-50%) rotate(405deg)}
\ No newline at end of file
diff --git a/procentric/application/css/jquery-ticker/ticker-style.css b/procentric/application/css/jquery-ticker/ticker-style.css
new file mode 100755
index 0000000..ca3c273
--- /dev/null
+++ b/procentric/application/css/jquery-ticker/ticker-style.css
@@ -0,0 +1,146 @@
+/* Ticker Styling */
+.ticker-wrapper.has-js {
+ margin: 20px 0px 20px 0px;
+ padding: 0px 20px;
+ width: 780px;
+ height: 32px;
+ display: block;
+ -webkit-border-radius: 15px;
+ -moz-border-radius: 15px;
+ border-radius: 15px;
+ background-color: #f8f0db;
+ font-size: 0.75em;
+}
+.ticker {
+ width: 710px;
+ height: 23px;
+ display: block;
+ position: relative;
+ overflow: hidden;
+ background-color: #f8f0db;
+}
+.ticker-title {
+ padding-top: 9px;
+ color: #990000;
+ font-weight: bold;
+ background-color: #f8f0db;
+ text-transform: uppercase;
+}
+.ticker-content {
+ margin: 0px;
+ padding-top: 9px;
+ position: absolute;
+ color: #1F527B;
+ font-weight: bold;
+ background-color: #f8f0db;
+ overflow: hidden;
+ white-space: nowrap;
+ line-height: 1.2em;
+}
+.ticker-content:focus {
+ none;
+}
+.ticker-content a {
+ text-decoration: none;
+ color: #1F527B;
+}
+.ticker-content a:hover {
+ text-decoration: underline;
+ color: #0D3059;
+}
+.ticker-swipe {
+ padding-top: 9px;
+ position: absolute;
+ top: 0px;
+ background-color: #f8f0db;
+ display: block;
+ width: 800px;
+ height: 23px;
+}
+.ticker-swipe span {
+ margin-left: 1px;
+ background-color: #f8f0db;
+ border-bottom: 1px solid #1F527B;
+ height: 12px;
+ width: 7px;
+ display: block;
+}
+.ticker-controls {
+ padding: 8px 0px 0px 0px;
+ list-style-type: none;
+ float: left;
+}
+.ticker-controls li {
+ padding: 0px;
+ margin-left: 5px;
+ float: left;
+ cursor: pointer;
+ height: 16px;
+ width: 16px;
+ display: block;
+}
+.ticker-controls li.jnt-play-pause {
+ background-image: url('../images/controls.png');
+ background-position: 32px 16px;
+}
+.ticker-controls li.jnt-play-pause.over {
+ background-position: 32px 32px;
+}
+.ticker-controls li.jnt-play-pause.down {
+ background-position: 32px 0px;
+}
+.ticker-controls li.jnt-play-pause.paused {
+ background-image: url('../images/controls.png');
+ background-position: 48px 16px;
+}
+.ticker-controls li.jnt-play-pause.paused.over {
+ background-position: 48px 32px;
+}
+.ticker-controls li.jnt-play-pause.paused.down {
+ background-position: 48px 0px;
+}
+.ticker-controls li.jnt-prev {
+ background-image: url('../images/controls.png');
+ background-position: 0px 16px;
+}
+.ticker-controls li.jnt-prev.over {
+ background-position: 0px 32px;
+}
+.ticker-controls li.jnt-prev.down {
+ background-position: 0px 0px;
+}
+.ticker-controls li.jnt-next {
+ background-image: url('../images/controls.png');
+ background-position: 16px 16px;
+}
+.ticker-controls li.jnt-next.over {
+ background-position: 16px 32px;
+}
+.ticker-controls li.jnt-next.down {
+ background-position: 16px 0px;
+}
+.js-hidden {
+ display: none;
+}
+.no-js-news {
+ padding: 10px 0px 0px 45px;
+ color: #F8F0DB;
+}
+.left .ticker-swipe {
+ /*left: 80px;*/
+}
+.left .ticker-controls, .left .ticker-content, .left .ticker-title, .left .ticker {
+ float: left;
+}
+.left .ticker-controls {
+ padding-left: 6px;
+}
+.right .ticker-swipe {
+ /*right: 80px;*/
+}
+.right .ticker-controls, .right .ticker-content, .right .ticker-title, .right .ticker {
+ float: right;
+}
+.right .ticker-controls {
+ padding-right: 6px;
+}
\ No newline at end of file
diff --git a/procentric/application/css/lightslider.css b/procentric/application/css/lightslider.css
new file mode 100755
index 0000000..9a2606e
--- /dev/null
+++ b/procentric/application/css/lightslider.css
@@ -0,0 +1,392 @@
+/*! lightslider - v1.1.3 - 2015-04-14
+* https://github.com/sachinchoolur/lightslider
+* Copyright (c) 2015 Sachin N; Licensed MIT */
+/** /!!! core css Should not edit !!!/**/
+
+.lSSlideOuter {
+ overflow: hidden;
+ -webkit-touch-callout: none;
+ -webkit-user-select: none;
+ -khtml-user-select: none;
+ -moz-user-select: none;
+ -ms-user-select: none;
+ user-select: none
+}
+.lightSlider:before, .lightSlider:after {
+ content: " ";
+ display: table;
+}
+.lightSlider {
+ overflow: hidden;
+ margin: 0;
+}
+.lSSlideWrapper {
+ max-width: 100%;
+ overflow: hidden;
+ position: relative;
+}
+.lSSlideWrapper > .lightSlider:after {
+ clear: both;
+}
+.lSSlideWrapper .lSSlide {
+ -webkit-transform: translate(0px, 0px);
+ -ms-transform: translate(0px, 0px);
+ transform: translate(0px, 0px);
+ -webkit-transition: all 1s;
+ -webkit-transition-property: -webkit-transform,height;
+ -moz-transition-property: -moz-transform,height;
+ transition-property: transform,height;
+ -webkit-transition-duration: inherit !important;
+ transition-duration: inherit !important;
+ -webkit-transition-timing-function: inherit !important;
+ transition-timing-function: inherit !important;
+}
+.lSSlideWrapper .lSFade {
+ position: relative;
+}
+.lSSlideWrapper .lSFade > * {
+ position: absolute !important;
+ top: 0;
+ left: 0;
+ z-index: 9;
+ margin-right: 0;
+ width: 100%;
+}
+.lSSlideWrapper.usingCss .lSFade > * {
+ opacity: 0;
+ -webkit-transition-delay: 0s;
+ transition-delay: 0s;
+ -webkit-transition-duration: inherit !important;
+ transition-duration: inherit !important;
+ -webkit-transition-property: opacity;
+ transition-property: opacity;
+ -webkit-transition-timing-function: inherit !important;
+ transition-timing-function: inherit !important;
+}
+.lSSlideWrapper .lSFade > *.active {
+ z-index: 10;
+}
+.lSSlideWrapper.usingCss .lSFade > *.active {
+ opacity: 1;
+}
+/** /!!! End of core css Should not edit !!!/**/
+
+/* Pager */
+.lSSlideOuter .lSPager.lSpg {
+ margin: 10px 0 0;
+ padding: 0;
+ text-align: center;
+}
+.lSSlideOuter .lSPager.lSpg > li {
+ cursor: pointer;
+ display: inline-block;
+ padding: 0 5px;
+}
+.lSSlideOuter .lSPager.lSpg > li a {
+ background-color: #222222;
+ border-radius: 30px;
+ display: inline-block;
+ height: 8px;
+ overflow: hidden;
+ text-indent: -999em;
+ width: 8px;
+ position: relative;
+ z-index: 99;
+ -webkit-transition: all 0.5s linear 0s;
+ transition: all 0.5s linear 0s;
+}
+.lSSlideOuter .lSPager.lSpg > li:hover a, .lSSlideOuter .lSPager.lSpg > li.active a {
+ background-color: #428bca;
+}
+.lSSlideOuter .media {
+ opacity: 0.8;
+}
+.lSSlideOuter .media.active {
+ opacity: 1;
+}
+/* End of pager */
+
+/** Gallery */
+.lSSlideOuter .lSPager.lSGallery {
+ list-style: none outside none;
+ padding-left: 0;
+ margin: 0;
+ overflow: hidden;
+ transform: translate3d(0px, 0px, 0px);
+ -moz-transform: translate3d(0px, 0px, 0px);
+ -ms-transform: translate3d(0px, 0px, 0px);
+ -webkit-transform: translate3d(0px, 0px, 0px);
+ -o-transform: translate3d(0px, 0px, 0px);
+ -webkit-transition-property: -webkit-transform;
+ -moz-transition-property: -moz-transform;
+ -webkit-touch-callout: none;
+ -webkit-user-select: none;
+ -khtml-user-select: none;
+ -moz-user-select: none;
+ -ms-user-select: none;
+ user-select: none;
+}
+.lSSlideOuter .lSPager.lSGallery li {
+ overflow: hidden;
+ -webkit-transition: border-radius 0.12s linear 0s 0.35s linear 0s;
+ transition: border-radius 0.12s linear 0s 0.35s linear 0s;
+}
+.lSSlideOuter .lSPager.lSGallery li.active, .lSSlideOuter .lSPager.lSGallery li:hover {
+ border-radius: 5px;
+}
+.lSSlideOuter .lSPager.lSGallery img {
+ display: block;
+ height: auto;
+ max-width: 100%;
+}
+.lSSlideOuter .lSPager.lSGallery:before, .lSSlideOuter .lSPager.lSGallery:after {
+ content: " ";
+ display: table;
+}
+.lSSlideOuter .lSPager.lSGallery:after {
+ clear: both;
+}
+/* End of Gallery*/
+
+/* slider actions */
+.lSAction > a {
+ width: 32px;
+ display: block;
+ top: 50%;
+ height: 32px;
+ background-image: url('../img/controls.png');
+ cursor: pointer;
+ position: absolute;
+ z-index: 99;
+ margin-top: -16px;
+ opacity: 0.5;
+ -webkit-transition: opacity 0.35s linear 0s;
+ transition: opacity 0.35s linear 0s;
+}
+.lSAction > a:hover {
+ opacity: 1;
+}
+.lSAction > .lSPrev {
+ background-position: 0 0;
+ left: 10px;
+}
+.lSAction > .lSNext {
+ background-position: -32px 0;
+ right: 10px;
+}
+.lSAction > a.disabled {
+ pointer-events: none;
+}
+.cS-hidden {
+ height: 1px;
+ opacity: 0;
+ filter: alpha(opacity=0);
+ overflow: hidden;
+}
+
+
+/* vertical */
+.lSSlideOuter.vertical {
+ position: relative;
+}
+.lSSlideOuter.vertical.noPager {
+ padding-right: 0px !important;
+}
+.lSSlideOuter.vertical .lSGallery {
+ position: absolute !important;
+ right: 0;
+ top: 0;
+}
+.lSSlideOuter.vertical .lightSlider > * {
+ width: 100% !important;
+ max-width: none !important;
+}
+
+/* vertical controlls */
+.lSSlideOuter.vertical .lSAction > a {
+ left: 50%;
+ margin-left: -14px;
+ margin-top: 0;
+}
+.lSSlideOuter.vertical .lSAction > .lSNext {
+ background-position: 31px -31px;
+ bottom: 10px;
+ top: auto;
+}
+.lSSlideOuter.vertical .lSAction > .lSPrev {
+ background-position: 0 -31px;
+ bottom: auto;
+ top: 10px;
+}
+/* vertical */
+
+
+/* Rtl */
+.lSSlideOuter.lSrtl {
+ direction: rtl;
+}
+.lSSlideOuter .lightSlider, .lSSlideOuter .lSPager {
+ padding-left: 0;
+ list-style: none outside none;
+}
+.lSSlideOuter.lSrtl .lightSlider, .lSSlideOuter.lSrtl .lSPager {
+ padding-right: 0;
+}
+.lSSlideOuter .lightSlider > *, .lSSlideOuter .lSGallery li {
+ float: left;
+}
+.lSSlideOuter.lSrtl .lightSlider > *, .lSSlideOuter.lSrtl .lSGallery li {
+ float: right !important;
+}
+/* Rtl */
+
+@-webkit-keyframes rightEnd {
+ 0% {
+ left: 0;
+ }
+
+ 50% {
+ left: -15px;
+ }
+
+ 100% {
+ left: 0;
+ }
+}
+@keyframes rightEnd {
+ 0% {
+ left: 0;
+ }
+
+ 50% {
+ left: -15px;
+ }
+
+ 100% {
+ left: 0;
+ }
+}
+@-webkit-keyframes topEnd {
+ 0% {
+ top: 0;
+ }
+
+ 50% {
+ top: -15px;
+ }
+
+ 100% {
+ top: 0;
+ }
+}
+@keyframes topEnd {
+ 0% {
+ top: 0;
+ }
+
+ 50% {
+ top: -15px;
+ }
+
+ 100% {
+ top: 0;
+ }
+}
+@-webkit-keyframes leftEnd {
+ 0% {
+ left: 0;
+ }
+
+ 50% {
+ left: 15px;
+ }
+
+ 100% {
+ left: 0;
+ }
+}
+@keyframes leftEnd {
+ 0% {
+ left: 0;
+ }
+
+ 50% {
+ left: 15px;
+ }
+
+ 100% {
+ left: 0;
+ }
+}
+@-webkit-keyframes bottomEnd {
+ 0% {
+ bottom: 0;
+ }
+
+ 50% {
+ bottom: -15px;
+ }
+
+ 100% {
+ bottom: 0;
+ }
+}
+@keyframes bottomEnd {
+ 0% {
+ bottom: 0;
+ }
+
+ 50% {
+ bottom: -15px;
+ }
+
+ 100% {
+ bottom: 0;
+ }
+}
+.lSSlideOuter .rightEnd {
+ -webkit-animation: rightEnd 0.3s;
+ animation: rightEnd 0.3s;
+ position: relative;
+}
+.lSSlideOuter .leftEnd {
+ -webkit-animation: leftEnd 0.3s;
+ animation: leftEnd 0.3s;
+ position: relative;
+}
+.lSSlideOuter.vertical .rightEnd {
+ -webkit-animation: topEnd 0.3s;
+ animation: topEnd 0.3s;
+ position: relative;
+}
+.lSSlideOuter.vertical .leftEnd {
+ -webkit-animation: bottomEnd 0.3s;
+ animation: bottomEnd 0.3s;
+ position: relative;
+}
+.lSSlideOuter.lSrtl .rightEnd {
+ -webkit-animation: leftEnd 0.3s;
+ animation: leftEnd 0.3s;
+ position: relative;
+}
+.lSSlideOuter.lSrtl .leftEnd {
+ -webkit-animation: rightEnd 0.3s;
+ animation: rightEnd 0.3s;
+ position: relative;
+}
+/*/ GRab cursor */
+.lightSlider.lsGrab > * {
+ cursor: -webkit-grab;
+ cursor: -moz-grab;
+ cursor: -o-grab;
+ cursor: -ms-grab;
+ cursor: grab;
+}
+.lightSlider.lsGrabbing > * {
+ cursor: move;
+ cursor: -webkit-grabbing;
+ cursor: -moz-grabbing;
+ cursor: -o-grabbing;
+ cursor: -ms-grabbing;
+ cursor: grabbing;
+}
\ No newline at end of file
diff --git a/procentric/application/css/owlcarousel/ajax-loader.gif b/procentric/application/css/owlcarousel/ajax-loader.gif
new file mode 100755
index 0000000..d3962f9
Binary files /dev/null and b/procentric/application/css/owlcarousel/ajax-loader.gif differ
diff --git a/procentric/application/css/owlcarousel/animate.min.css b/procentric/application/css/owlcarousel/animate.min.css
new file mode 100644
index 0000000..76d2fe1
--- /dev/null
+++ b/procentric/application/css/owlcarousel/animate.min.css
@@ -0,0 +1,7 @@
+@charset "UTF-8";/*!
+ * animate.css - https://animate.style/
+ * Version - 4.1.1
+ * Licensed under the MIT license - http://opensource.org/licenses/MIT
+ *
+ * Copyright (c) 2020 Animate.css
+ */:root{--animate-duration:1s;--animate-delay:1s;--animate-repeat:1}.animate__animated{-webkit-animation-duration:1s;animation-duration:1s;-webkit-animation-duration:var(--animate-duration);animation-duration:var(--animate-duration);-webkit-animation-fill-mode:both;animation-fill-mode:both}.animate__animated.animate__infinite{-webkit-animation-iteration-count:infinite;animation-iteration-count:infinite}.animate__animated.animate__repeat-1{-webkit-animation-iteration-count:1;animation-iteration-count:1;-webkit-animation-iteration-count:var(--animate-repeat);animation-iteration-count:var(--animate-repeat)}.animate__animated.animate__repeat-2{-webkit-animation-iteration-count:2;animation-iteration-count:2;-webkit-animation-iteration-count:calc(var(--animate-repeat)*2);animation-iteration-count:calc(var(--animate-repeat)*2)}.animate__animated.animate__repeat-3{-webkit-animation-iteration-count:3;animation-iteration-count:3;-webkit-animation-iteration-count:calc(var(--animate-repeat)*3);animation-iteration-count:calc(var(--animate-repeat)*3)}.animate__animated.animate__delay-1s{-webkit-animation-delay:1s;animation-delay:1s;-webkit-animation-delay:var(--animate-delay);animation-delay:var(--animate-delay)}.animate__animated.animate__delay-2s{-webkit-animation-delay:2s;animation-delay:2s;-webkit-animation-delay:calc(var(--animate-delay)*2);animation-delay:calc(var(--animate-delay)*2)}.animate__animated.animate__delay-3s{-webkit-animation-delay:3s;animation-delay:3s;-webkit-animation-delay:calc(var(--animate-delay)*3);animation-delay:calc(var(--animate-delay)*3)}.animate__animated.animate__delay-4s{-webkit-animation-delay:4s;animation-delay:4s;-webkit-animation-delay:calc(var(--animate-delay)*4);animation-delay:calc(var(--animate-delay)*4)}.animate__animated.animate__delay-5s{-webkit-animation-delay:5s;animation-delay:5s;-webkit-animation-delay:calc(var(--animate-delay)*5);animation-delay:calc(var(--animate-delay)*5)}.animate__animated.animate__faster{-webkit-animation-duration:.5s;animation-duration:.5s;-webkit-animation-duration:calc(var(--animate-duration)/2);animation-duration:calc(var(--animate-duration)/2)}.animate__animated.animate__fast{-webkit-animation-duration:.8s;animation-duration:.8s;-webkit-animation-duration:calc(var(--animate-duration)*0.8);animation-duration:calc(var(--animate-duration)*0.8)}.animate__animated.animate__slow{-webkit-animation-duration:2s;animation-duration:2s;-webkit-animation-duration:calc(var(--animate-duration)*2);animation-duration:calc(var(--animate-duration)*2)}.animate__animated.animate__slower{-webkit-animation-duration:3s;animation-duration:3s;-webkit-animation-duration:calc(var(--animate-duration)*3);animation-duration:calc(var(--animate-duration)*3)}@media (prefers-reduced-motion:reduce),print{.animate__animated{-webkit-animation-duration:1ms!important;animation-duration:1ms!important;-webkit-transition-duration:1ms!important;transition-duration:1ms!important;-webkit-animation-iteration-count:1!important;animation-iteration-count:1!important}.animate__animated[class*=Out]{opacity:0}}@-webkit-keyframes bounce{0%,20%,53%,to{-webkit-animation-timing-function:cubic-bezier(.215,.61,.355,1);animation-timing-function:cubic-bezier(.215,.61,.355,1);-webkit-transform:translateZ(0);transform:translateZ(0)}40%,43%{-webkit-animation-timing-function:cubic-bezier(.755,.05,.855,.06);animation-timing-function:cubic-bezier(.755,.05,.855,.06);-webkit-transform:translate3d(0,-30px,0) scaleY(1.1);transform:translate3d(0,-30px,0) scaleY(1.1)}70%{-webkit-animation-timing-function:cubic-bezier(.755,.05,.855,.06);animation-timing-function:cubic-bezier(.755,.05,.855,.06);-webkit-transform:translate3d(0,-15px,0) scaleY(1.05);transform:translate3d(0,-15px,0) scaleY(1.05)}80%{-webkit-transition-timing-function:cubic-bezier(.215,.61,.355,1);transition-timing-function:cubic-bezier(.215,.61,.355,1);-webkit-transform:translateZ(0) scaleY(.95);transform:translateZ(0) scaleY(.95)}90%{-webkit-transform:translate3d(0,-4px,0) scaleY(1.02);transform:translate3d(0,-4px,0) scaleY(1.02)}}@keyframes bounce{0%,20%,53%,to{-webkit-animation-timing-function:cubic-bezier(.215,.61,.355,1);animation-timing-function:cubic-bezier(.215,.61,.355,1);-webkit-transform:translateZ(0);transform:translateZ(0)}40%,43%{-webkit-animation-timing-function:cubic-bezier(.755,.05,.855,.06);animation-timing-function:cubic-bezier(.755,.05,.855,.06);-webkit-transform:translate3d(0,-30px,0) scaleY(1.1);transform:translate3d(0,-30px,0) scaleY(1.1)}70%{-webkit-animation-timing-function:cubic-bezier(.755,.05,.855,.06);animation-timing-function:cubic-bezier(.755,.05,.855,.06);-webkit-transform:translate3d(0,-15px,0) scaleY(1.05);transform:translate3d(0,-15px,0) scaleY(1.05)}80%{-webkit-transition-timing-function:cubic-bezier(.215,.61,.355,1);transition-timing-function:cubic-bezier(.215,.61,.355,1);-webkit-transform:translateZ(0) scaleY(.95);transform:translateZ(0) scaleY(.95)}90%{-webkit-transform:translate3d(0,-4px,0) scaleY(1.02);transform:translate3d(0,-4px,0) scaleY(1.02)}}.animate__bounce{-webkit-animation-name:bounce;animation-name:bounce;-webkit-transform-origin:center bottom;transform-origin:center bottom}@-webkit-keyframes flash{0%,50%,to{opacity:1}25%,75%{opacity:0}}@keyframes flash{0%,50%,to{opacity:1}25%,75%{opacity:0}}.animate__flash{-webkit-animation-name:flash;animation-name:flash}@-webkit-keyframes pulse{0%{-webkit-transform:scaleX(1);transform:scaleX(1)}50%{-webkit-transform:scale3d(1.05,1.05,1.05);transform:scale3d(1.05,1.05,1.05)}to{-webkit-transform:scaleX(1);transform:scaleX(1)}}@keyframes pulse{0%{-webkit-transform:scaleX(1);transform:scaleX(1)}50%{-webkit-transform:scale3d(1.05,1.05,1.05);transform:scale3d(1.05,1.05,1.05)}to{-webkit-transform:scaleX(1);transform:scaleX(1)}}.animate__pulse{-webkit-animation-name:pulse;animation-name:pulse;-webkit-animation-timing-function:ease-in-out;animation-timing-function:ease-in-out}@-webkit-keyframes rubberBand{0%{-webkit-transform:scaleX(1);transform:scaleX(1)}30%{-webkit-transform:scale3d(1.25,.75,1);transform:scale3d(1.25,.75,1)}40%{-webkit-transform:scale3d(.75,1.25,1);transform:scale3d(.75,1.25,1)}50%{-webkit-transform:scale3d(1.15,.85,1);transform:scale3d(1.15,.85,1)}65%{-webkit-transform:scale3d(.95,1.05,1);transform:scale3d(.95,1.05,1)}75%{-webkit-transform:scale3d(1.05,.95,1);transform:scale3d(1.05,.95,1)}to{-webkit-transform:scaleX(1);transform:scaleX(1)}}@keyframes rubberBand{0%{-webkit-transform:scaleX(1);transform:scaleX(1)}30%{-webkit-transform:scale3d(1.25,.75,1);transform:scale3d(1.25,.75,1)}40%{-webkit-transform:scale3d(.75,1.25,1);transform:scale3d(.75,1.25,1)}50%{-webkit-transform:scale3d(1.15,.85,1);transform:scale3d(1.15,.85,1)}65%{-webkit-transform:scale3d(.95,1.05,1);transform:scale3d(.95,1.05,1)}75%{-webkit-transform:scale3d(1.05,.95,1);transform:scale3d(1.05,.95,1)}to{-webkit-transform:scaleX(1);transform:scaleX(1)}}.animate__rubberBand{-webkit-animation-name:rubberBand;animation-name:rubberBand}@-webkit-keyframes shakeX{0%,to{-webkit-transform:translateZ(0);transform:translateZ(0)}10%,30%,50%,70%,90%{-webkit-transform:translate3d(-10px,0,0);transform:translate3d(-10px,0,0)}20%,40%,60%,80%{-webkit-transform:translate3d(10px,0,0);transform:translate3d(10px,0,0)}}@keyframes shakeX{0%,to{-webkit-transform:translateZ(0);transform:translateZ(0)}10%,30%,50%,70%,90%{-webkit-transform:translate3d(-10px,0,0);transform:translate3d(-10px,0,0)}20%,40%,60%,80%{-webkit-transform:translate3d(10px,0,0);transform:translate3d(10px,0,0)}}.animate__shakeX{-webkit-animation-name:shakeX;animation-name:shakeX}@-webkit-keyframes shakeY{0%,to{-webkit-transform:translateZ(0);transform:translateZ(0)}10%,30%,50%,70%,90%{-webkit-transform:translate3d(0,-10px,0);transform:translate3d(0,-10px,0)}20%,40%,60%,80%{-webkit-transform:translate3d(0,10px,0);transform:translate3d(0,10px,0)}}@keyframes shakeY{0%,to{-webkit-transform:translateZ(0);transform:translateZ(0)}10%,30%,50%,70%,90%{-webkit-transform:translate3d(0,-10px,0);transform:translate3d(0,-10px,0)}20%,40%,60%,80%{-webkit-transform:translate3d(0,10px,0);transform:translate3d(0,10px,0)}}.animate__shakeY{-webkit-animation-name:shakeY;animation-name:shakeY}@-webkit-keyframes headShake{0%{-webkit-transform:translateX(0);transform:translateX(0)}6.5%{-webkit-transform:translateX(-6px) rotateY(-9deg);transform:translateX(-6px) rotateY(-9deg)}18.5%{-webkit-transform:translateX(5px) rotateY(7deg);transform:translateX(5px) rotateY(7deg)}31.5%{-webkit-transform:translateX(-3px) rotateY(-5deg);transform:translateX(-3px) rotateY(-5deg)}43.5%{-webkit-transform:translateX(2px) rotateY(3deg);transform:translateX(2px) rotateY(3deg)}50%{-webkit-transform:translateX(0);transform:translateX(0)}}@keyframes headShake{0%{-webkit-transform:translateX(0);transform:translateX(0)}6.5%{-webkit-transform:translateX(-6px) rotateY(-9deg);transform:translateX(-6px) rotateY(-9deg)}18.5%{-webkit-transform:translateX(5px) rotateY(7deg);transform:translateX(5px) rotateY(7deg)}31.5%{-webkit-transform:translateX(-3px) rotateY(-5deg);transform:translateX(-3px) rotateY(-5deg)}43.5%{-webkit-transform:translateX(2px) rotateY(3deg);transform:translateX(2px) rotateY(3deg)}50%{-webkit-transform:translateX(0);transform:translateX(0)}}.animate__headShake{-webkit-animation-timing-function:ease-in-out;animation-timing-function:ease-in-out;-webkit-animation-name:headShake;animation-name:headShake}@-webkit-keyframes swing{20%{-webkit-transform:rotate(15deg);transform:rotate(15deg)}40%{-webkit-transform:rotate(-10deg);transform:rotate(-10deg)}60%{-webkit-transform:rotate(5deg);transform:rotate(5deg)}80%{-webkit-transform:rotate(-5deg);transform:rotate(-5deg)}to{-webkit-transform:rotate(0deg);transform:rotate(0deg)}}@keyframes swing{20%{-webkit-transform:rotate(15deg);transform:rotate(15deg)}40%{-webkit-transform:rotate(-10deg);transform:rotate(-10deg)}60%{-webkit-transform:rotate(5deg);transform:rotate(5deg)}80%{-webkit-transform:rotate(-5deg);transform:rotate(-5deg)}to{-webkit-transform:rotate(0deg);transform:rotate(0deg)}}.animate__swing{-webkit-transform-origin:top center;transform-origin:top center;-webkit-animation-name:swing;animation-name:swing}@-webkit-keyframes tada{0%{-webkit-transform:scaleX(1);transform:scaleX(1)}10%,20%{-webkit-transform:scale3d(.9,.9,.9) rotate(-3deg);transform:scale3d(.9,.9,.9) rotate(-3deg)}30%,50%,70%,90%{-webkit-transform:scale3d(1.1,1.1,1.1) rotate(3deg);transform:scale3d(1.1,1.1,1.1) rotate(3deg)}40%,60%,80%{-webkit-transform:scale3d(1.1,1.1,1.1) rotate(-3deg);transform:scale3d(1.1,1.1,1.1) rotate(-3deg)}to{-webkit-transform:scaleX(1);transform:scaleX(1)}}@keyframes tada{0%{-webkit-transform:scaleX(1);transform:scaleX(1)}10%,20%{-webkit-transform:scale3d(.9,.9,.9) rotate(-3deg);transform:scale3d(.9,.9,.9) rotate(-3deg)}30%,50%,70%,90%{-webkit-transform:scale3d(1.1,1.1,1.1) rotate(3deg);transform:scale3d(1.1,1.1,1.1) rotate(3deg)}40%,60%,80%{-webkit-transform:scale3d(1.1,1.1,1.1) rotate(-3deg);transform:scale3d(1.1,1.1,1.1) rotate(-3deg)}to{-webkit-transform:scaleX(1);transform:scaleX(1)}}.animate__tada{-webkit-animation-name:tada;animation-name:tada}@-webkit-keyframes wobble{0%{-webkit-transform:translateZ(0);transform:translateZ(0)}15%{-webkit-transform:translate3d(-25%,0,0) rotate(-5deg);transform:translate3d(-25%,0,0) rotate(-5deg)}30%{-webkit-transform:translate3d(20%,0,0) rotate(3deg);transform:translate3d(20%,0,0) rotate(3deg)}45%{-webkit-transform:translate3d(-15%,0,0) rotate(-3deg);transform:translate3d(-15%,0,0) rotate(-3deg)}60%{-webkit-transform:translate3d(10%,0,0) rotate(2deg);transform:translate3d(10%,0,0) rotate(2deg)}75%{-webkit-transform:translate3d(-5%,0,0) rotate(-1deg);transform:translate3d(-5%,0,0) rotate(-1deg)}to{-webkit-transform:translateZ(0);transform:translateZ(0)}}@keyframes wobble{0%{-webkit-transform:translateZ(0);transform:translateZ(0)}15%{-webkit-transform:translate3d(-25%,0,0) rotate(-5deg);transform:translate3d(-25%,0,0) rotate(-5deg)}30%{-webkit-transform:translate3d(20%,0,0) rotate(3deg);transform:translate3d(20%,0,0) rotate(3deg)}45%{-webkit-transform:translate3d(-15%,0,0) rotate(-3deg);transform:translate3d(-15%,0,0) rotate(-3deg)}60%{-webkit-transform:translate3d(10%,0,0) rotate(2deg);transform:translate3d(10%,0,0) rotate(2deg)}75%{-webkit-transform:translate3d(-5%,0,0) rotate(-1deg);transform:translate3d(-5%,0,0) rotate(-1deg)}to{-webkit-transform:translateZ(0);transform:translateZ(0)}}.animate__wobble{-webkit-animation-name:wobble;animation-name:wobble}@-webkit-keyframes jello{0%,11.1%,to{-webkit-transform:translateZ(0);transform:translateZ(0)}22.2%{-webkit-transform:skewX(-12.5deg) skewY(-12.5deg);transform:skewX(-12.5deg) skewY(-12.5deg)}33.3%{-webkit-transform:skewX(6.25deg) skewY(6.25deg);transform:skewX(6.25deg) skewY(6.25deg)}44.4%{-webkit-transform:skewX(-3.125deg) skewY(-3.125deg);transform:skewX(-3.125deg) skewY(-3.125deg)}55.5%{-webkit-transform:skewX(1.5625deg) skewY(1.5625deg);transform:skewX(1.5625deg) skewY(1.5625deg)}66.6%{-webkit-transform:skewX(-.78125deg) skewY(-.78125deg);transform:skewX(-.78125deg) skewY(-.78125deg)}77.7%{-webkit-transform:skewX(.390625deg) skewY(.390625deg);transform:skewX(.390625deg) skewY(.390625deg)}88.8%{-webkit-transform:skewX(-.1953125deg) skewY(-.1953125deg);transform:skewX(-.1953125deg) skewY(-.1953125deg)}}@keyframes jello{0%,11.1%,to{-webkit-transform:translateZ(0);transform:translateZ(0)}22.2%{-webkit-transform:skewX(-12.5deg) skewY(-12.5deg);transform:skewX(-12.5deg) skewY(-12.5deg)}33.3%{-webkit-transform:skewX(6.25deg) skewY(6.25deg);transform:skewX(6.25deg) skewY(6.25deg)}44.4%{-webkit-transform:skewX(-3.125deg) skewY(-3.125deg);transform:skewX(-3.125deg) skewY(-3.125deg)}55.5%{-webkit-transform:skewX(1.5625deg) skewY(1.5625deg);transform:skewX(1.5625deg) skewY(1.5625deg)}66.6%{-webkit-transform:skewX(-.78125deg) skewY(-.78125deg);transform:skewX(-.78125deg) skewY(-.78125deg)}77.7%{-webkit-transform:skewX(.390625deg) skewY(.390625deg);transform:skewX(.390625deg) skewY(.390625deg)}88.8%{-webkit-transform:skewX(-.1953125deg) skewY(-.1953125deg);transform:skewX(-.1953125deg) skewY(-.1953125deg)}}.animate__jello{-webkit-animation-name:jello;animation-name:jello;-webkit-transform-origin:center;transform-origin:center}@-webkit-keyframes heartBeat{0%{-webkit-transform:scale(1);transform:scale(1)}14%{-webkit-transform:scale(1.3);transform:scale(1.3)}28%{-webkit-transform:scale(1);transform:scale(1)}42%{-webkit-transform:scale(1.3);transform:scale(1.3)}70%{-webkit-transform:scale(1);transform:scale(1)}}@keyframes heartBeat{0%{-webkit-transform:scale(1);transform:scale(1)}14%{-webkit-transform:scale(1.3);transform:scale(1.3)}28%{-webkit-transform:scale(1);transform:scale(1)}42%{-webkit-transform:scale(1.3);transform:scale(1.3)}70%{-webkit-transform:scale(1);transform:scale(1)}}.animate__heartBeat{-webkit-animation-name:heartBeat;animation-name:heartBeat;-webkit-animation-duration:1.3s;animation-duration:1.3s;-webkit-animation-duration:calc(var(--animate-duration)*1.3);animation-duration:calc(var(--animate-duration)*1.3);-webkit-animation-timing-function:ease-in-out;animation-timing-function:ease-in-out}@-webkit-keyframes backInDown{0%{-webkit-transform:translateY(-1200px) scale(.7);transform:translateY(-1200px) scale(.7);opacity:.7}80%{-webkit-transform:translateY(0) scale(.7);transform:translateY(0) scale(.7);opacity:.7}to{-webkit-transform:scale(1);transform:scale(1);opacity:1}}@keyframes backInDown{0%{-webkit-transform:translateY(-1200px) scale(.7);transform:translateY(-1200px) scale(.7);opacity:.7}80%{-webkit-transform:translateY(0) scale(.7);transform:translateY(0) scale(.7);opacity:.7}to{-webkit-transform:scale(1);transform:scale(1);opacity:1}}.animate__backInDown{-webkit-animation-name:backInDown;animation-name:backInDown}@-webkit-keyframes backInLeft{0%{-webkit-transform:translateX(-2000px) scale(.7);transform:translateX(-2000px) scale(.7);opacity:.7}80%{-webkit-transform:translateX(0) scale(.7);transform:translateX(0) scale(.7);opacity:.7}to{-webkit-transform:scale(1);transform:scale(1);opacity:1}}@keyframes backInLeft{0%{-webkit-transform:translateX(-2000px) scale(.7);transform:translateX(-2000px) scale(.7);opacity:.7}80%{-webkit-transform:translateX(0) scale(.7);transform:translateX(0) scale(.7);opacity:.7}to{-webkit-transform:scale(1);transform:scale(1);opacity:1}}.animate__backInLeft{-webkit-animation-name:backInLeft;animation-name:backInLeft}@-webkit-keyframes backInRight{0%{-webkit-transform:translateX(2000px) scale(.7);transform:translateX(2000px) scale(.7);opacity:.7}80%{-webkit-transform:translateX(0) scale(.7);transform:translateX(0) scale(.7);opacity:.7}to{-webkit-transform:scale(1);transform:scale(1);opacity:1}}@keyframes backInRight{0%{-webkit-transform:translateX(2000px) scale(.7);transform:translateX(2000px) scale(.7);opacity:.7}80%{-webkit-transform:translateX(0) scale(.7);transform:translateX(0) scale(.7);opacity:.7}to{-webkit-transform:scale(1);transform:scale(1);opacity:1}}.animate__backInRight{-webkit-animation-name:backInRight;animation-name:backInRight}@-webkit-keyframes backInUp{0%{-webkit-transform:translateY(1200px) scale(.7);transform:translateY(1200px) scale(.7);opacity:.7}80%{-webkit-transform:translateY(0) scale(.7);transform:translateY(0) scale(.7);opacity:.7}to{-webkit-transform:scale(1);transform:scale(1);opacity:1}}@keyframes backInUp{0%{-webkit-transform:translateY(1200px) scale(.7);transform:translateY(1200px) scale(.7);opacity:.7}80%{-webkit-transform:translateY(0) scale(.7);transform:translateY(0) scale(.7);opacity:.7}to{-webkit-transform:scale(1);transform:scale(1);opacity:1}}.animate__backInUp{-webkit-animation-name:backInUp;animation-name:backInUp}@-webkit-keyframes backOutDown{0%{-webkit-transform:scale(1);transform:scale(1);opacity:1}20%{-webkit-transform:translateY(0) scale(.7);transform:translateY(0) scale(.7);opacity:.7}to{-webkit-transform:translateY(700px) scale(.7);transform:translateY(700px) scale(.7);opacity:.7}}@keyframes backOutDown{0%{-webkit-transform:scale(1);transform:scale(1);opacity:1}20%{-webkit-transform:translateY(0) scale(.7);transform:translateY(0) scale(.7);opacity:.7}to{-webkit-transform:translateY(700px) scale(.7);transform:translateY(700px) scale(.7);opacity:.7}}.animate__backOutDown{-webkit-animation-name:backOutDown;animation-name:backOutDown}@-webkit-keyframes backOutLeft{0%{-webkit-transform:scale(1);transform:scale(1);opacity:1}20%{-webkit-transform:translateX(0) scale(.7);transform:translateX(0) scale(.7);opacity:.7}to{-webkit-transform:translateX(-2000px) scale(.7);transform:translateX(-2000px) scale(.7);opacity:.7}}@keyframes backOutLeft{0%{-webkit-transform:scale(1);transform:scale(1);opacity:1}20%{-webkit-transform:translateX(0) scale(.7);transform:translateX(0) scale(.7);opacity:.7}to{-webkit-transform:translateX(-2000px) scale(.7);transform:translateX(-2000px) scale(.7);opacity:.7}}.animate__backOutLeft{-webkit-animation-name:backOutLeft;animation-name:backOutLeft}@-webkit-keyframes backOutRight{0%{-webkit-transform:scale(1);transform:scale(1);opacity:1}20%{-webkit-transform:translateX(0) scale(.7);transform:translateX(0) scale(.7);opacity:.7}to{-webkit-transform:translateX(2000px) scale(.7);transform:translateX(2000px) scale(.7);opacity:.7}}@keyframes backOutRight{0%{-webkit-transform:scale(1);transform:scale(1);opacity:1}20%{-webkit-transform:translateX(0) scale(.7);transform:translateX(0) scale(.7);opacity:.7}to{-webkit-transform:translateX(2000px) scale(.7);transform:translateX(2000px) scale(.7);opacity:.7}}.animate__backOutRight{-webkit-animation-name:backOutRight;animation-name:backOutRight}@-webkit-keyframes backOutUp{0%{-webkit-transform:scale(1);transform:scale(1);opacity:1}20%{-webkit-transform:translateY(0) scale(.7);transform:translateY(0) scale(.7);opacity:.7}to{-webkit-transform:translateY(-700px) scale(.7);transform:translateY(-700px) scale(.7);opacity:.7}}@keyframes backOutUp{0%{-webkit-transform:scale(1);transform:scale(1);opacity:1}20%{-webkit-transform:translateY(0) scale(.7);transform:translateY(0) scale(.7);opacity:.7}to{-webkit-transform:translateY(-700px) scale(.7);transform:translateY(-700px) scale(.7);opacity:.7}}.animate__backOutUp{-webkit-animation-name:backOutUp;animation-name:backOutUp}@-webkit-keyframes bounceIn{0%,20%,40%,60%,80%,to{-webkit-animation-timing-function:cubic-bezier(.215,.61,.355,1);animation-timing-function:cubic-bezier(.215,.61,.355,1)}0%{opacity:0;-webkit-transform:scale3d(.3,.3,.3);transform:scale3d(.3,.3,.3)}20%{-webkit-transform:scale3d(1.1,1.1,1.1);transform:scale3d(1.1,1.1,1.1)}40%{-webkit-transform:scale3d(.9,.9,.9);transform:scale3d(.9,.9,.9)}60%{opacity:1;-webkit-transform:scale3d(1.03,1.03,1.03);transform:scale3d(1.03,1.03,1.03)}80%{-webkit-transform:scale3d(.97,.97,.97);transform:scale3d(.97,.97,.97)}to{opacity:1;-webkit-transform:scaleX(1);transform:scaleX(1)}}@keyframes bounceIn{0%,20%,40%,60%,80%,to{-webkit-animation-timing-function:cubic-bezier(.215,.61,.355,1);animation-timing-function:cubic-bezier(.215,.61,.355,1)}0%{opacity:0;-webkit-transform:scale3d(.3,.3,.3);transform:scale3d(.3,.3,.3)}20%{-webkit-transform:scale3d(1.1,1.1,1.1);transform:scale3d(1.1,1.1,1.1)}40%{-webkit-transform:scale3d(.9,.9,.9);transform:scale3d(.9,.9,.9)}60%{opacity:1;-webkit-transform:scale3d(1.03,1.03,1.03);transform:scale3d(1.03,1.03,1.03)}80%{-webkit-transform:scale3d(.97,.97,.97);transform:scale3d(.97,.97,.97)}to{opacity:1;-webkit-transform:scaleX(1);transform:scaleX(1)}}.animate__bounceIn{-webkit-animation-duration:.75s;animation-duration:.75s;-webkit-animation-duration:calc(var(--animate-duration)*0.75);animation-duration:calc(var(--animate-duration)*0.75);-webkit-animation-name:bounceIn;animation-name:bounceIn}@-webkit-keyframes bounceInDown{0%,60%,75%,90%,to{-webkit-animation-timing-function:cubic-bezier(.215,.61,.355,1);animation-timing-function:cubic-bezier(.215,.61,.355,1)}0%{opacity:0;-webkit-transform:translate3d(0,-3000px,0) scaleY(3);transform:translate3d(0,-3000px,0) scaleY(3)}60%{opacity:1;-webkit-transform:translate3d(0,25px,0) scaleY(.9);transform:translate3d(0,25px,0) scaleY(.9)}75%{-webkit-transform:translate3d(0,-10px,0) scaleY(.95);transform:translate3d(0,-10px,0) scaleY(.95)}90%{-webkit-transform:translate3d(0,5px,0) scaleY(.985);transform:translate3d(0,5px,0) scaleY(.985)}to{-webkit-transform:translateZ(0);transform:translateZ(0)}}@keyframes bounceInDown{0%,60%,75%,90%,to{-webkit-animation-timing-function:cubic-bezier(.215,.61,.355,1);animation-timing-function:cubic-bezier(.215,.61,.355,1)}0%{opacity:0;-webkit-transform:translate3d(0,-3000px,0) scaleY(3);transform:translate3d(0,-3000px,0) scaleY(3)}60%{opacity:1;-webkit-transform:translate3d(0,25px,0) scaleY(.9);transform:translate3d(0,25px,0) scaleY(.9)}75%{-webkit-transform:translate3d(0,-10px,0) scaleY(.95);transform:translate3d(0,-10px,0) scaleY(.95)}90%{-webkit-transform:translate3d(0,5px,0) scaleY(.985);transform:translate3d(0,5px,0) scaleY(.985)}to{-webkit-transform:translateZ(0);transform:translateZ(0)}}.animate__bounceInDown{-webkit-animation-name:bounceInDown;animation-name:bounceInDown}@-webkit-keyframes bounceInLeft{0%,60%,75%,90%,to{-webkit-animation-timing-function:cubic-bezier(.215,.61,.355,1);animation-timing-function:cubic-bezier(.215,.61,.355,1)}0%{opacity:0;-webkit-transform:translate3d(-3000px,0,0) scaleX(3);transform:translate3d(-3000px,0,0) scaleX(3)}60%{opacity:1;-webkit-transform:translate3d(25px,0,0) scaleX(1);transform:translate3d(25px,0,0) scaleX(1)}75%{-webkit-transform:translate3d(-10px,0,0) scaleX(.98);transform:translate3d(-10px,0,0) scaleX(.98)}90%{-webkit-transform:translate3d(5px,0,0) scaleX(.995);transform:translate3d(5px,0,0) scaleX(.995)}to{-webkit-transform:translateZ(0);transform:translateZ(0)}}@keyframes bounceInLeft{0%,60%,75%,90%,to{-webkit-animation-timing-function:cubic-bezier(.215,.61,.355,1);animation-timing-function:cubic-bezier(.215,.61,.355,1)}0%{opacity:0;-webkit-transform:translate3d(-3000px,0,0) scaleX(3);transform:translate3d(-3000px,0,0) scaleX(3)}60%{opacity:1;-webkit-transform:translate3d(25px,0,0) scaleX(1);transform:translate3d(25px,0,0) scaleX(1)}75%{-webkit-transform:translate3d(-10px,0,0) scaleX(.98);transform:translate3d(-10px,0,0) scaleX(.98)}90%{-webkit-transform:translate3d(5px,0,0) scaleX(.995);transform:translate3d(5px,0,0) scaleX(.995)}to{-webkit-transform:translateZ(0);transform:translateZ(0)}}.animate__bounceInLeft{-webkit-animation-name:bounceInLeft;animation-name:bounceInLeft}@-webkit-keyframes bounceInRight{0%,60%,75%,90%,to{-webkit-animation-timing-function:cubic-bezier(.215,.61,.355,1);animation-timing-function:cubic-bezier(.215,.61,.355,1)}0%{opacity:0;-webkit-transform:translate3d(3000px,0,0) scaleX(3);transform:translate3d(3000px,0,0) scaleX(3)}60%{opacity:1;-webkit-transform:translate3d(-25px,0,0) scaleX(1);transform:translate3d(-25px,0,0) scaleX(1)}75%{-webkit-transform:translate3d(10px,0,0) scaleX(.98);transform:translate3d(10px,0,0) scaleX(.98)}90%{-webkit-transform:translate3d(-5px,0,0) scaleX(.995);transform:translate3d(-5px,0,0) scaleX(.995)}to{-webkit-transform:translateZ(0);transform:translateZ(0)}}@keyframes bounceInRight{0%,60%,75%,90%,to{-webkit-animation-timing-function:cubic-bezier(.215,.61,.355,1);animation-timing-function:cubic-bezier(.215,.61,.355,1)}0%{opacity:0;-webkit-transform:translate3d(3000px,0,0) scaleX(3);transform:translate3d(3000px,0,0) scaleX(3)}60%{opacity:1;-webkit-transform:translate3d(-25px,0,0) scaleX(1);transform:translate3d(-25px,0,0) scaleX(1)}75%{-webkit-transform:translate3d(10px,0,0) scaleX(.98);transform:translate3d(10px,0,0) scaleX(.98)}90%{-webkit-transform:translate3d(-5px,0,0) scaleX(.995);transform:translate3d(-5px,0,0) scaleX(.995)}to{-webkit-transform:translateZ(0);transform:translateZ(0)}}.animate__bounceInRight{-webkit-animation-name:bounceInRight;animation-name:bounceInRight}@-webkit-keyframes bounceInUp{0%,60%,75%,90%,to{-webkit-animation-timing-function:cubic-bezier(.215,.61,.355,1);animation-timing-function:cubic-bezier(.215,.61,.355,1)}0%{opacity:0;-webkit-transform:translate3d(0,3000px,0) scaleY(5);transform:translate3d(0,3000px,0) scaleY(5)}60%{opacity:1;-webkit-transform:translate3d(0,-20px,0) scaleY(.9);transform:translate3d(0,-20px,0) scaleY(.9)}75%{-webkit-transform:translate3d(0,10px,0) scaleY(.95);transform:translate3d(0,10px,0) scaleY(.95)}90%{-webkit-transform:translate3d(0,-5px,0) scaleY(.985);transform:translate3d(0,-5px,0) scaleY(.985)}to{-webkit-transform:translateZ(0);transform:translateZ(0)}}@keyframes bounceInUp{0%,60%,75%,90%,to{-webkit-animation-timing-function:cubic-bezier(.215,.61,.355,1);animation-timing-function:cubic-bezier(.215,.61,.355,1)}0%{opacity:0;-webkit-transform:translate3d(0,3000px,0) scaleY(5);transform:translate3d(0,3000px,0) scaleY(5)}60%{opacity:1;-webkit-transform:translate3d(0,-20px,0) scaleY(.9);transform:translate3d(0,-20px,0) scaleY(.9)}75%{-webkit-transform:translate3d(0,10px,0) scaleY(.95);transform:translate3d(0,10px,0) scaleY(.95)}90%{-webkit-transform:translate3d(0,-5px,0) scaleY(.985);transform:translate3d(0,-5px,0) scaleY(.985)}to{-webkit-transform:translateZ(0);transform:translateZ(0)}}.animate__bounceInUp{-webkit-animation-name:bounceInUp;animation-name:bounceInUp}@-webkit-keyframes bounceOut{20%{-webkit-transform:scale3d(.9,.9,.9);transform:scale3d(.9,.9,.9)}50%,55%{opacity:1;-webkit-transform:scale3d(1.1,1.1,1.1);transform:scale3d(1.1,1.1,1.1)}to{opacity:0;-webkit-transform:scale3d(.3,.3,.3);transform:scale3d(.3,.3,.3)}}@keyframes bounceOut{20%{-webkit-transform:scale3d(.9,.9,.9);transform:scale3d(.9,.9,.9)}50%,55%{opacity:1;-webkit-transform:scale3d(1.1,1.1,1.1);transform:scale3d(1.1,1.1,1.1)}to{opacity:0;-webkit-transform:scale3d(.3,.3,.3);transform:scale3d(.3,.3,.3)}}.animate__bounceOut{-webkit-animation-duration:.75s;animation-duration:.75s;-webkit-animation-duration:calc(var(--animate-duration)*0.75);animation-duration:calc(var(--animate-duration)*0.75);-webkit-animation-name:bounceOut;animation-name:bounceOut}@-webkit-keyframes bounceOutDown{20%{-webkit-transform:translate3d(0,10px,0) scaleY(.985);transform:translate3d(0,10px,0) scaleY(.985)}40%,45%{opacity:1;-webkit-transform:translate3d(0,-20px,0) scaleY(.9);transform:translate3d(0,-20px,0) scaleY(.9)}to{opacity:0;-webkit-transform:translate3d(0,2000px,0) scaleY(3);transform:translate3d(0,2000px,0) scaleY(3)}}@keyframes bounceOutDown{20%{-webkit-transform:translate3d(0,10px,0) scaleY(.985);transform:translate3d(0,10px,0) scaleY(.985)}40%,45%{opacity:1;-webkit-transform:translate3d(0,-20px,0) scaleY(.9);transform:translate3d(0,-20px,0) scaleY(.9)}to{opacity:0;-webkit-transform:translate3d(0,2000px,0) scaleY(3);transform:translate3d(0,2000px,0) scaleY(3)}}.animate__bounceOutDown{-webkit-animation-name:bounceOutDown;animation-name:bounceOutDown}@-webkit-keyframes bounceOutLeft{20%{opacity:1;-webkit-transform:translate3d(20px,0,0) scaleX(.9);transform:translate3d(20px,0,0) scaleX(.9)}to{opacity:0;-webkit-transform:translate3d(-2000px,0,0) scaleX(2);transform:translate3d(-2000px,0,0) scaleX(2)}}@keyframes bounceOutLeft{20%{opacity:1;-webkit-transform:translate3d(20px,0,0) scaleX(.9);transform:translate3d(20px,0,0) scaleX(.9)}to{opacity:0;-webkit-transform:translate3d(-2000px,0,0) scaleX(2);transform:translate3d(-2000px,0,0) scaleX(2)}}.animate__bounceOutLeft{-webkit-animation-name:bounceOutLeft;animation-name:bounceOutLeft}@-webkit-keyframes bounceOutRight{20%{opacity:1;-webkit-transform:translate3d(-20px,0,0) scaleX(.9);transform:translate3d(-20px,0,0) scaleX(.9)}to{opacity:0;-webkit-transform:translate3d(2000px,0,0) scaleX(2);transform:translate3d(2000px,0,0) scaleX(2)}}@keyframes bounceOutRight{20%{opacity:1;-webkit-transform:translate3d(-20px,0,0) scaleX(.9);transform:translate3d(-20px,0,0) scaleX(.9)}to{opacity:0;-webkit-transform:translate3d(2000px,0,0) scaleX(2);transform:translate3d(2000px,0,0) scaleX(2)}}.animate__bounceOutRight{-webkit-animation-name:bounceOutRight;animation-name:bounceOutRight}@-webkit-keyframes bounceOutUp{20%{-webkit-transform:translate3d(0,-10px,0) scaleY(.985);transform:translate3d(0,-10px,0) scaleY(.985)}40%,45%{opacity:1;-webkit-transform:translate3d(0,20px,0) scaleY(.9);transform:translate3d(0,20px,0) scaleY(.9)}to{opacity:0;-webkit-transform:translate3d(0,-2000px,0) scaleY(3);transform:translate3d(0,-2000px,0) scaleY(3)}}@keyframes bounceOutUp{20%{-webkit-transform:translate3d(0,-10px,0) scaleY(.985);transform:translate3d(0,-10px,0) scaleY(.985)}40%,45%{opacity:1;-webkit-transform:translate3d(0,20px,0) scaleY(.9);transform:translate3d(0,20px,0) scaleY(.9)}to{opacity:0;-webkit-transform:translate3d(0,-2000px,0) scaleY(3);transform:translate3d(0,-2000px,0) scaleY(3)}}.animate__bounceOutUp{-webkit-animation-name:bounceOutUp;animation-name:bounceOutUp}@-webkit-keyframes fadeIn{0%{opacity:0}to{opacity:1}}@keyframes fadeIn{0%{opacity:0}to{opacity:1}}.animate__fadeIn{-webkit-animation-name:fadeIn;animation-name:fadeIn}@-webkit-keyframes fadeInDown{0%{opacity:0;-webkit-transform:translate3d(0,-100%,0);transform:translate3d(0,-100%,0)}to{opacity:1;-webkit-transform:translateZ(0);transform:translateZ(0)}}@keyframes fadeInDown{0%{opacity:0;-webkit-transform:translate3d(0,-100%,0);transform:translate3d(0,-100%,0)}to{opacity:1;-webkit-transform:translateZ(0);transform:translateZ(0)}}.animate__fadeInDown{-webkit-animation-name:fadeInDown;animation-name:fadeInDown}@-webkit-keyframes fadeInDownBig{0%{opacity:0;-webkit-transform:translate3d(0,-2000px,0);transform:translate3d(0,-2000px,0)}to{opacity:1;-webkit-transform:translateZ(0);transform:translateZ(0)}}@keyframes fadeInDownBig{0%{opacity:0;-webkit-transform:translate3d(0,-2000px,0);transform:translate3d(0,-2000px,0)}to{opacity:1;-webkit-transform:translateZ(0);transform:translateZ(0)}}.animate__fadeInDownBig{-webkit-animation-name:fadeInDownBig;animation-name:fadeInDownBig}@-webkit-keyframes fadeInLeft{0%{opacity:0;-webkit-transform:translate3d(-100%,0,0);transform:translate3d(-100%,0,0)}to{opacity:1;-webkit-transform:translateZ(0);transform:translateZ(0)}}@keyframes fadeInLeft{0%{opacity:0;-webkit-transform:translate3d(-100%,0,0);transform:translate3d(-100%,0,0)}to{opacity:1;-webkit-transform:translateZ(0);transform:translateZ(0)}}.animate__fadeInLeft{-webkit-animation-name:fadeInLeft;animation-name:fadeInLeft}@-webkit-keyframes fadeInLeftBig{0%{opacity:0;-webkit-transform:translate3d(-2000px,0,0);transform:translate3d(-2000px,0,0)}to{opacity:1;-webkit-transform:translateZ(0);transform:translateZ(0)}}@keyframes fadeInLeftBig{0%{opacity:0;-webkit-transform:translate3d(-2000px,0,0);transform:translate3d(-2000px,0,0)}to{opacity:1;-webkit-transform:translateZ(0);transform:translateZ(0)}}.animate__fadeInLeftBig{-webkit-animation-name:fadeInLeftBig;animation-name:fadeInLeftBig}@-webkit-keyframes fadeInRight{0%{opacity:0;-webkit-transform:translate3d(100%,0,0);transform:translate3d(100%,0,0)}to{opacity:1;-webkit-transform:translateZ(0);transform:translateZ(0)}}@keyframes fadeInRight{0%{opacity:0;-webkit-transform:translate3d(100%,0,0);transform:translate3d(100%,0,0)}to{opacity:1;-webkit-transform:translateZ(0);transform:translateZ(0)}}.animate__fadeInRight{-webkit-animation-name:fadeInRight;animation-name:fadeInRight}@-webkit-keyframes fadeInRightBig{0%{opacity:0;-webkit-transform:translate3d(2000px,0,0);transform:translate3d(2000px,0,0)}to{opacity:1;-webkit-transform:translateZ(0);transform:translateZ(0)}}@keyframes fadeInRightBig{0%{opacity:0;-webkit-transform:translate3d(2000px,0,0);transform:translate3d(2000px,0,0)}to{opacity:1;-webkit-transform:translateZ(0);transform:translateZ(0)}}.animate__fadeInRightBig{-webkit-animation-name:fadeInRightBig;animation-name:fadeInRightBig}@-webkit-keyframes fadeInUp{0%{opacity:0;-webkit-transform:translate3d(0,100%,0);transform:translate3d(0,100%,0)}to{opacity:1;-webkit-transform:translateZ(0);transform:translateZ(0)}}@keyframes fadeInUp{0%{opacity:0;-webkit-transform:translate3d(0,100%,0);transform:translate3d(0,100%,0)}to{opacity:1;-webkit-transform:translateZ(0);transform:translateZ(0)}}.animate__fadeInUp{-webkit-animation-name:fadeInUp;animation-name:fadeInUp}@-webkit-keyframes fadeInUpBig{0%{opacity:0;-webkit-transform:translate3d(0,2000px,0);transform:translate3d(0,2000px,0)}to{opacity:1;-webkit-transform:translateZ(0);transform:translateZ(0)}}@keyframes fadeInUpBig{0%{opacity:0;-webkit-transform:translate3d(0,2000px,0);transform:translate3d(0,2000px,0)}to{opacity:1;-webkit-transform:translateZ(0);transform:translateZ(0)}}.animate__fadeInUpBig{-webkit-animation-name:fadeInUpBig;animation-name:fadeInUpBig}@-webkit-keyframes fadeInTopLeft{0%{opacity:0;-webkit-transform:translate3d(-100%,-100%,0);transform:translate3d(-100%,-100%,0)}to{opacity:1;-webkit-transform:translateZ(0);transform:translateZ(0)}}@keyframes fadeInTopLeft{0%{opacity:0;-webkit-transform:translate3d(-100%,-100%,0);transform:translate3d(-100%,-100%,0)}to{opacity:1;-webkit-transform:translateZ(0);transform:translateZ(0)}}.animate__fadeInTopLeft{-webkit-animation-name:fadeInTopLeft;animation-name:fadeInTopLeft}@-webkit-keyframes fadeInTopRight{0%{opacity:0;-webkit-transform:translate3d(100%,-100%,0);transform:translate3d(100%,-100%,0)}to{opacity:1;-webkit-transform:translateZ(0);transform:translateZ(0)}}@keyframes fadeInTopRight{0%{opacity:0;-webkit-transform:translate3d(100%,-100%,0);transform:translate3d(100%,-100%,0)}to{opacity:1;-webkit-transform:translateZ(0);transform:translateZ(0)}}.animate__fadeInTopRight{-webkit-animation-name:fadeInTopRight;animation-name:fadeInTopRight}@-webkit-keyframes fadeInBottomLeft{0%{opacity:0;-webkit-transform:translate3d(-100%,100%,0);transform:translate3d(-100%,100%,0)}to{opacity:1;-webkit-transform:translateZ(0);transform:translateZ(0)}}@keyframes fadeInBottomLeft{0%{opacity:0;-webkit-transform:translate3d(-100%,100%,0);transform:translate3d(-100%,100%,0)}to{opacity:1;-webkit-transform:translateZ(0);transform:translateZ(0)}}.animate__fadeInBottomLeft{-webkit-animation-name:fadeInBottomLeft;animation-name:fadeInBottomLeft}@-webkit-keyframes fadeInBottomRight{0%{opacity:0;-webkit-transform:translate3d(100%,100%,0);transform:translate3d(100%,100%,0)}to{opacity:1;-webkit-transform:translateZ(0);transform:translateZ(0)}}@keyframes fadeInBottomRight{0%{opacity:0;-webkit-transform:translate3d(100%,100%,0);transform:translate3d(100%,100%,0)}to{opacity:1;-webkit-transform:translateZ(0);transform:translateZ(0)}}.animate__fadeInBottomRight{-webkit-animation-name:fadeInBottomRight;animation-name:fadeInBottomRight}@-webkit-keyframes fadeOut{0%{opacity:1}to{opacity:0}}@keyframes fadeOut{0%{opacity:1}to{opacity:0}}.animate__fadeOut{-webkit-animation-name:fadeOut;animation-name:fadeOut}@-webkit-keyframes fadeOutDown{0%{opacity:1}to{opacity:0;-webkit-transform:translate3d(0,100%,0);transform:translate3d(0,100%,0)}}@keyframes fadeOutDown{0%{opacity:1}to{opacity:0;-webkit-transform:translate3d(0,100%,0);transform:translate3d(0,100%,0)}}.animate__fadeOutDown{-webkit-animation-name:fadeOutDown;animation-name:fadeOutDown}@-webkit-keyframes fadeOutDownBig{0%{opacity:1}to{opacity:0;-webkit-transform:translate3d(0,2000px,0);transform:translate3d(0,2000px,0)}}@keyframes fadeOutDownBig{0%{opacity:1}to{opacity:0;-webkit-transform:translate3d(0,2000px,0);transform:translate3d(0,2000px,0)}}.animate__fadeOutDownBig{-webkit-animation-name:fadeOutDownBig;animation-name:fadeOutDownBig}@-webkit-keyframes fadeOutLeft{0%{opacity:1}to{opacity:0;-webkit-transform:translate3d(-100%,0,0);transform:translate3d(-100%,0,0)}}@keyframes fadeOutLeft{0%{opacity:1}to{opacity:0;-webkit-transform:translate3d(-100%,0,0);transform:translate3d(-100%,0,0)}}.animate__fadeOutLeft{-webkit-animation-name:fadeOutLeft;animation-name:fadeOutLeft}@-webkit-keyframes fadeOutLeftBig{0%{opacity:1}to{opacity:0;-webkit-transform:translate3d(-2000px,0,0);transform:translate3d(-2000px,0,0)}}@keyframes fadeOutLeftBig{0%{opacity:1}to{opacity:0;-webkit-transform:translate3d(-2000px,0,0);transform:translate3d(-2000px,0,0)}}.animate__fadeOutLeftBig{-webkit-animation-name:fadeOutLeftBig;animation-name:fadeOutLeftBig}@-webkit-keyframes fadeOutRight{0%{opacity:1}to{opacity:0;-webkit-transform:translate3d(100%,0,0);transform:translate3d(100%,0,0)}}@keyframes fadeOutRight{0%{opacity:1}to{opacity:0;-webkit-transform:translate3d(100%,0,0);transform:translate3d(100%,0,0)}}.animate__fadeOutRight{-webkit-animation-name:fadeOutRight;animation-name:fadeOutRight}@-webkit-keyframes fadeOutRightBig{0%{opacity:1}to{opacity:0;-webkit-transform:translate3d(2000px,0,0);transform:translate3d(2000px,0,0)}}@keyframes fadeOutRightBig{0%{opacity:1}to{opacity:0;-webkit-transform:translate3d(2000px,0,0);transform:translate3d(2000px,0,0)}}.animate__fadeOutRightBig{-webkit-animation-name:fadeOutRightBig;animation-name:fadeOutRightBig}@-webkit-keyframes fadeOutUp{0%{opacity:1}to{opacity:0;-webkit-transform:translate3d(0,-100%,0);transform:translate3d(0,-100%,0)}}@keyframes fadeOutUp{0%{opacity:1}to{opacity:0;-webkit-transform:translate3d(0,-100%,0);transform:translate3d(0,-100%,0)}}.animate__fadeOutUp{-webkit-animation-name:fadeOutUp;animation-name:fadeOutUp}@-webkit-keyframes fadeOutUpBig{0%{opacity:1}to{opacity:0;-webkit-transform:translate3d(0,-2000px,0);transform:translate3d(0,-2000px,0)}}@keyframes fadeOutUpBig{0%{opacity:1}to{opacity:0;-webkit-transform:translate3d(0,-2000px,0);transform:translate3d(0,-2000px,0)}}.animate__fadeOutUpBig{-webkit-animation-name:fadeOutUpBig;animation-name:fadeOutUpBig}@-webkit-keyframes fadeOutTopLeft{0%{opacity:1;-webkit-transform:translateZ(0);transform:translateZ(0)}to{opacity:0;-webkit-transform:translate3d(-100%,-100%,0);transform:translate3d(-100%,-100%,0)}}@keyframes fadeOutTopLeft{0%{opacity:1;-webkit-transform:translateZ(0);transform:translateZ(0)}to{opacity:0;-webkit-transform:translate3d(-100%,-100%,0);transform:translate3d(-100%,-100%,0)}}.animate__fadeOutTopLeft{-webkit-animation-name:fadeOutTopLeft;animation-name:fadeOutTopLeft}@-webkit-keyframes fadeOutTopRight{0%{opacity:1;-webkit-transform:translateZ(0);transform:translateZ(0)}to{opacity:0;-webkit-transform:translate3d(100%,-100%,0);transform:translate3d(100%,-100%,0)}}@keyframes fadeOutTopRight{0%{opacity:1;-webkit-transform:translateZ(0);transform:translateZ(0)}to{opacity:0;-webkit-transform:translate3d(100%,-100%,0);transform:translate3d(100%,-100%,0)}}.animate__fadeOutTopRight{-webkit-animation-name:fadeOutTopRight;animation-name:fadeOutTopRight}@-webkit-keyframes fadeOutBottomRight{0%{opacity:1;-webkit-transform:translateZ(0);transform:translateZ(0)}to{opacity:0;-webkit-transform:translate3d(100%,100%,0);transform:translate3d(100%,100%,0)}}@keyframes fadeOutBottomRight{0%{opacity:1;-webkit-transform:translateZ(0);transform:translateZ(0)}to{opacity:0;-webkit-transform:translate3d(100%,100%,0);transform:translate3d(100%,100%,0)}}.animate__fadeOutBottomRight{-webkit-animation-name:fadeOutBottomRight;animation-name:fadeOutBottomRight}@-webkit-keyframes fadeOutBottomLeft{0%{opacity:1;-webkit-transform:translateZ(0);transform:translateZ(0)}to{opacity:0;-webkit-transform:translate3d(-100%,100%,0);transform:translate3d(-100%,100%,0)}}@keyframes fadeOutBottomLeft{0%{opacity:1;-webkit-transform:translateZ(0);transform:translateZ(0)}to{opacity:0;-webkit-transform:translate3d(-100%,100%,0);transform:translate3d(-100%,100%,0)}}.animate__fadeOutBottomLeft{-webkit-animation-name:fadeOutBottomLeft;animation-name:fadeOutBottomLeft}@-webkit-keyframes flip{0%{-webkit-transform:perspective(400px) scaleX(1) translateZ(0) rotateY(-1turn);transform:perspective(400px) scaleX(1) translateZ(0) rotateY(-1turn);-webkit-animation-timing-function:ease-out;animation-timing-function:ease-out}40%{-webkit-transform:perspective(400px) scaleX(1) translateZ(150px) rotateY(-190deg);transform:perspective(400px) scaleX(1) translateZ(150px) rotateY(-190deg);-webkit-animation-timing-function:ease-out;animation-timing-function:ease-out}50%{-webkit-transform:perspective(400px) scaleX(1) translateZ(150px) rotateY(-170deg);transform:perspective(400px) scaleX(1) translateZ(150px) rotateY(-170deg);-webkit-animation-timing-function:ease-in;animation-timing-function:ease-in}80%{-webkit-transform:perspective(400px) scale3d(.95,.95,.95) translateZ(0) rotateY(0deg);transform:perspective(400px) scale3d(.95,.95,.95) translateZ(0) rotateY(0deg);-webkit-animation-timing-function:ease-in;animation-timing-function:ease-in}to{-webkit-transform:perspective(400px) scaleX(1) translateZ(0) rotateY(0deg);transform:perspective(400px) scaleX(1) translateZ(0) rotateY(0deg);-webkit-animation-timing-function:ease-in;animation-timing-function:ease-in}}@keyframes flip{0%{-webkit-transform:perspective(400px) scaleX(1) translateZ(0) rotateY(-1turn);transform:perspective(400px) scaleX(1) translateZ(0) rotateY(-1turn);-webkit-animation-timing-function:ease-out;animation-timing-function:ease-out}40%{-webkit-transform:perspective(400px) scaleX(1) translateZ(150px) rotateY(-190deg);transform:perspective(400px) scaleX(1) translateZ(150px) rotateY(-190deg);-webkit-animation-timing-function:ease-out;animation-timing-function:ease-out}50%{-webkit-transform:perspective(400px) scaleX(1) translateZ(150px) rotateY(-170deg);transform:perspective(400px) scaleX(1) translateZ(150px) rotateY(-170deg);-webkit-animation-timing-function:ease-in;animation-timing-function:ease-in}80%{-webkit-transform:perspective(400px) scale3d(.95,.95,.95) translateZ(0) rotateY(0deg);transform:perspective(400px) scale3d(.95,.95,.95) translateZ(0) rotateY(0deg);-webkit-animation-timing-function:ease-in;animation-timing-function:ease-in}to{-webkit-transform:perspective(400px) scaleX(1) translateZ(0) rotateY(0deg);transform:perspective(400px) scaleX(1) translateZ(0) rotateY(0deg);-webkit-animation-timing-function:ease-in;animation-timing-function:ease-in}}.animate__animated.animate__flip{-webkit-backface-visibility:visible;backface-visibility:visible;-webkit-animation-name:flip;animation-name:flip}@-webkit-keyframes flipInX{0%{-webkit-transform:perspective(400px) rotateX(90deg);transform:perspective(400px) rotateX(90deg);-webkit-animation-timing-function:ease-in;animation-timing-function:ease-in;opacity:0}40%{-webkit-transform:perspective(400px) rotateX(-20deg);transform:perspective(400px) rotateX(-20deg);-webkit-animation-timing-function:ease-in;animation-timing-function:ease-in}60%{-webkit-transform:perspective(400px) rotateX(10deg);transform:perspective(400px) rotateX(10deg);opacity:1}80%{-webkit-transform:perspective(400px) rotateX(-5deg);transform:perspective(400px) rotateX(-5deg)}to{-webkit-transform:perspective(400px);transform:perspective(400px)}}@keyframes flipInX{0%{-webkit-transform:perspective(400px) rotateX(90deg);transform:perspective(400px) rotateX(90deg);-webkit-animation-timing-function:ease-in;animation-timing-function:ease-in;opacity:0}40%{-webkit-transform:perspective(400px) rotateX(-20deg);transform:perspective(400px) rotateX(-20deg);-webkit-animation-timing-function:ease-in;animation-timing-function:ease-in}60%{-webkit-transform:perspective(400px) rotateX(10deg);transform:perspective(400px) rotateX(10deg);opacity:1}80%{-webkit-transform:perspective(400px) rotateX(-5deg);transform:perspective(400px) rotateX(-5deg)}to{-webkit-transform:perspective(400px);transform:perspective(400px)}}.animate__flipInX{-webkit-backface-visibility:visible!important;backface-visibility:visible!important;-webkit-animation-name:flipInX;animation-name:flipInX}@-webkit-keyframes flipInY{0%{-webkit-transform:perspective(400px) rotateY(90deg);transform:perspective(400px) rotateY(90deg);-webkit-animation-timing-function:ease-in;animation-timing-function:ease-in;opacity:0}40%{-webkit-transform:perspective(400px) rotateY(-20deg);transform:perspective(400px) rotateY(-20deg);-webkit-animation-timing-function:ease-in;animation-timing-function:ease-in}60%{-webkit-transform:perspective(400px) rotateY(10deg);transform:perspective(400px) rotateY(10deg);opacity:1}80%{-webkit-transform:perspective(400px) rotateY(-5deg);transform:perspective(400px) rotateY(-5deg)}to{-webkit-transform:perspective(400px);transform:perspective(400px)}}@keyframes flipInY{0%{-webkit-transform:perspective(400px) rotateY(90deg);transform:perspective(400px) rotateY(90deg);-webkit-animation-timing-function:ease-in;animation-timing-function:ease-in;opacity:0}40%{-webkit-transform:perspective(400px) rotateY(-20deg);transform:perspective(400px) rotateY(-20deg);-webkit-animation-timing-function:ease-in;animation-timing-function:ease-in}60%{-webkit-transform:perspective(400px) rotateY(10deg);transform:perspective(400px) rotateY(10deg);opacity:1}80%{-webkit-transform:perspective(400px) rotateY(-5deg);transform:perspective(400px) rotateY(-5deg)}to{-webkit-transform:perspective(400px);transform:perspective(400px)}}.animate__flipInY{-webkit-backface-visibility:visible!important;backface-visibility:visible!important;-webkit-animation-name:flipInY;animation-name:flipInY}@-webkit-keyframes flipOutX{0%{-webkit-transform:perspective(400px);transform:perspective(400px)}30%{-webkit-transform:perspective(400px) rotateX(-20deg);transform:perspective(400px) rotateX(-20deg);opacity:1}to{-webkit-transform:perspective(400px) rotateX(90deg);transform:perspective(400px) rotateX(90deg);opacity:0}}@keyframes flipOutX{0%{-webkit-transform:perspective(400px);transform:perspective(400px)}30%{-webkit-transform:perspective(400px) rotateX(-20deg);transform:perspective(400px) rotateX(-20deg);opacity:1}to{-webkit-transform:perspective(400px) rotateX(90deg);transform:perspective(400px) rotateX(90deg);opacity:0}}.animate__flipOutX{-webkit-animation-duration:.75s;animation-duration:.75s;-webkit-animation-duration:calc(var(--animate-duration)*0.75);animation-duration:calc(var(--animate-duration)*0.75);-webkit-animation-name:flipOutX;animation-name:flipOutX;-webkit-backface-visibility:visible!important;backface-visibility:visible!important}@-webkit-keyframes flipOutY{0%{-webkit-transform:perspective(400px);transform:perspective(400px)}30%{-webkit-transform:perspective(400px) rotateY(-15deg);transform:perspective(400px) rotateY(-15deg);opacity:1}to{-webkit-transform:perspective(400px) rotateY(90deg);transform:perspective(400px) rotateY(90deg);opacity:0}}@keyframes flipOutY{0%{-webkit-transform:perspective(400px);transform:perspective(400px)}30%{-webkit-transform:perspective(400px) rotateY(-15deg);transform:perspective(400px) rotateY(-15deg);opacity:1}to{-webkit-transform:perspective(400px) rotateY(90deg);transform:perspective(400px) rotateY(90deg);opacity:0}}.animate__flipOutY{-webkit-animation-duration:.75s;animation-duration:.75s;-webkit-animation-duration:calc(var(--animate-duration)*0.75);animation-duration:calc(var(--animate-duration)*0.75);-webkit-backface-visibility:visible!important;backface-visibility:visible!important;-webkit-animation-name:flipOutY;animation-name:flipOutY}@-webkit-keyframes lightSpeedInRight{0%{-webkit-transform:translate3d(100%,0,0) skewX(-30deg);transform:translate3d(100%,0,0) skewX(-30deg);opacity:0}60%{-webkit-transform:skewX(20deg);transform:skewX(20deg);opacity:1}80%{-webkit-transform:skewX(-5deg);transform:skewX(-5deg)}to{-webkit-transform:translateZ(0);transform:translateZ(0)}}@keyframes lightSpeedInRight{0%{-webkit-transform:translate3d(100%,0,0) skewX(-30deg);transform:translate3d(100%,0,0) skewX(-30deg);opacity:0}60%{-webkit-transform:skewX(20deg);transform:skewX(20deg);opacity:1}80%{-webkit-transform:skewX(-5deg);transform:skewX(-5deg)}to{-webkit-transform:translateZ(0);transform:translateZ(0)}}.animate__lightSpeedInRight{-webkit-animation-name:lightSpeedInRight;animation-name:lightSpeedInRight;-webkit-animation-timing-function:ease-out;animation-timing-function:ease-out}@-webkit-keyframes lightSpeedInLeft{0%{-webkit-transform:translate3d(-100%,0,0) skewX(30deg);transform:translate3d(-100%,0,0) skewX(30deg);opacity:0}60%{-webkit-transform:skewX(-20deg);transform:skewX(-20deg);opacity:1}80%{-webkit-transform:skewX(5deg);transform:skewX(5deg)}to{-webkit-transform:translateZ(0);transform:translateZ(0)}}@keyframes lightSpeedInLeft{0%{-webkit-transform:translate3d(-100%,0,0) skewX(30deg);transform:translate3d(-100%,0,0) skewX(30deg);opacity:0}60%{-webkit-transform:skewX(-20deg);transform:skewX(-20deg);opacity:1}80%{-webkit-transform:skewX(5deg);transform:skewX(5deg)}to{-webkit-transform:translateZ(0);transform:translateZ(0)}}.animate__lightSpeedInLeft{-webkit-animation-name:lightSpeedInLeft;animation-name:lightSpeedInLeft;-webkit-animation-timing-function:ease-out;animation-timing-function:ease-out}@-webkit-keyframes lightSpeedOutRight{0%{opacity:1}to{-webkit-transform:translate3d(100%,0,0) skewX(30deg);transform:translate3d(100%,0,0) skewX(30deg);opacity:0}}@keyframes lightSpeedOutRight{0%{opacity:1}to{-webkit-transform:translate3d(100%,0,0) skewX(30deg);transform:translate3d(100%,0,0) skewX(30deg);opacity:0}}.animate__lightSpeedOutRight{-webkit-animation-name:lightSpeedOutRight;animation-name:lightSpeedOutRight;-webkit-animation-timing-function:ease-in;animation-timing-function:ease-in}@-webkit-keyframes lightSpeedOutLeft{0%{opacity:1}to{-webkit-transform:translate3d(-100%,0,0) skewX(-30deg);transform:translate3d(-100%,0,0) skewX(-30deg);opacity:0}}@keyframes lightSpeedOutLeft{0%{opacity:1}to{-webkit-transform:translate3d(-100%,0,0) skewX(-30deg);transform:translate3d(-100%,0,0) skewX(-30deg);opacity:0}}.animate__lightSpeedOutLeft{-webkit-animation-name:lightSpeedOutLeft;animation-name:lightSpeedOutLeft;-webkit-animation-timing-function:ease-in;animation-timing-function:ease-in}@-webkit-keyframes rotateIn{0%{-webkit-transform:rotate(-200deg);transform:rotate(-200deg);opacity:0}to{-webkit-transform:translateZ(0);transform:translateZ(0);opacity:1}}@keyframes rotateIn{0%{-webkit-transform:rotate(-200deg);transform:rotate(-200deg);opacity:0}to{-webkit-transform:translateZ(0);transform:translateZ(0);opacity:1}}.animate__rotateIn{-webkit-animation-name:rotateIn;animation-name:rotateIn;-webkit-transform-origin:center;transform-origin:center}@-webkit-keyframes rotateInDownLeft{0%{-webkit-transform:rotate(-45deg);transform:rotate(-45deg);opacity:0}to{-webkit-transform:translateZ(0);transform:translateZ(0);opacity:1}}@keyframes rotateInDownLeft{0%{-webkit-transform:rotate(-45deg);transform:rotate(-45deg);opacity:0}to{-webkit-transform:translateZ(0);transform:translateZ(0);opacity:1}}.animate__rotateInDownLeft{-webkit-animation-name:rotateInDownLeft;animation-name:rotateInDownLeft;-webkit-transform-origin:left bottom;transform-origin:left bottom}@-webkit-keyframes rotateInDownRight{0%{-webkit-transform:rotate(45deg);transform:rotate(45deg);opacity:0}to{-webkit-transform:translateZ(0);transform:translateZ(0);opacity:1}}@keyframes rotateInDownRight{0%{-webkit-transform:rotate(45deg);transform:rotate(45deg);opacity:0}to{-webkit-transform:translateZ(0);transform:translateZ(0);opacity:1}}.animate__rotateInDownRight{-webkit-animation-name:rotateInDownRight;animation-name:rotateInDownRight;-webkit-transform-origin:right bottom;transform-origin:right bottom}@-webkit-keyframes rotateInUpLeft{0%{-webkit-transform:rotate(45deg);transform:rotate(45deg);opacity:0}to{-webkit-transform:translateZ(0);transform:translateZ(0);opacity:1}}@keyframes rotateInUpLeft{0%{-webkit-transform:rotate(45deg);transform:rotate(45deg);opacity:0}to{-webkit-transform:translateZ(0);transform:translateZ(0);opacity:1}}.animate__rotateInUpLeft{-webkit-animation-name:rotateInUpLeft;animation-name:rotateInUpLeft;-webkit-transform-origin:left bottom;transform-origin:left bottom}@-webkit-keyframes rotateInUpRight{0%{-webkit-transform:rotate(-90deg);transform:rotate(-90deg);opacity:0}to{-webkit-transform:translateZ(0);transform:translateZ(0);opacity:1}}@keyframes rotateInUpRight{0%{-webkit-transform:rotate(-90deg);transform:rotate(-90deg);opacity:0}to{-webkit-transform:translateZ(0);transform:translateZ(0);opacity:1}}.animate__rotateInUpRight{-webkit-animation-name:rotateInUpRight;animation-name:rotateInUpRight;-webkit-transform-origin:right bottom;transform-origin:right bottom}@-webkit-keyframes rotateOut{0%{opacity:1}to{-webkit-transform:rotate(200deg);transform:rotate(200deg);opacity:0}}@keyframes rotateOut{0%{opacity:1}to{-webkit-transform:rotate(200deg);transform:rotate(200deg);opacity:0}}.animate__rotateOut{-webkit-animation-name:rotateOut;animation-name:rotateOut;-webkit-transform-origin:center;transform-origin:center}@-webkit-keyframes rotateOutDownLeft{0%{opacity:1}to{-webkit-transform:rotate(45deg);transform:rotate(45deg);opacity:0}}@keyframes rotateOutDownLeft{0%{opacity:1}to{-webkit-transform:rotate(45deg);transform:rotate(45deg);opacity:0}}.animate__rotateOutDownLeft{-webkit-animation-name:rotateOutDownLeft;animation-name:rotateOutDownLeft;-webkit-transform-origin:left bottom;transform-origin:left bottom}@-webkit-keyframes rotateOutDownRight{0%{opacity:1}to{-webkit-transform:rotate(-45deg);transform:rotate(-45deg);opacity:0}}@keyframes rotateOutDownRight{0%{opacity:1}to{-webkit-transform:rotate(-45deg);transform:rotate(-45deg);opacity:0}}.animate__rotateOutDownRight{-webkit-animation-name:rotateOutDownRight;animation-name:rotateOutDownRight;-webkit-transform-origin:right bottom;transform-origin:right bottom}@-webkit-keyframes rotateOutUpLeft{0%{opacity:1}to{-webkit-transform:rotate(-45deg);transform:rotate(-45deg);opacity:0}}@keyframes rotateOutUpLeft{0%{opacity:1}to{-webkit-transform:rotate(-45deg);transform:rotate(-45deg);opacity:0}}.animate__rotateOutUpLeft{-webkit-animation-name:rotateOutUpLeft;animation-name:rotateOutUpLeft;-webkit-transform-origin:left bottom;transform-origin:left bottom}@-webkit-keyframes rotateOutUpRight{0%{opacity:1}to{-webkit-transform:rotate(90deg);transform:rotate(90deg);opacity:0}}@keyframes rotateOutUpRight{0%{opacity:1}to{-webkit-transform:rotate(90deg);transform:rotate(90deg);opacity:0}}.animate__rotateOutUpRight{-webkit-animation-name:rotateOutUpRight;animation-name:rotateOutUpRight;-webkit-transform-origin:right bottom;transform-origin:right bottom}@-webkit-keyframes hinge{0%{-webkit-animation-timing-function:ease-in-out;animation-timing-function:ease-in-out}20%,60%{-webkit-transform:rotate(80deg);transform:rotate(80deg);-webkit-animation-timing-function:ease-in-out;animation-timing-function:ease-in-out}40%,80%{-webkit-transform:rotate(60deg);transform:rotate(60deg);-webkit-animation-timing-function:ease-in-out;animation-timing-function:ease-in-out;opacity:1}to{-webkit-transform:translate3d(0,700px,0);transform:translate3d(0,700px,0);opacity:0}}@keyframes hinge{0%{-webkit-animation-timing-function:ease-in-out;animation-timing-function:ease-in-out}20%,60%{-webkit-transform:rotate(80deg);transform:rotate(80deg);-webkit-animation-timing-function:ease-in-out;animation-timing-function:ease-in-out}40%,80%{-webkit-transform:rotate(60deg);transform:rotate(60deg);-webkit-animation-timing-function:ease-in-out;animation-timing-function:ease-in-out;opacity:1}to{-webkit-transform:translate3d(0,700px,0);transform:translate3d(0,700px,0);opacity:0}}.animate__hinge{-webkit-animation-duration:2s;animation-duration:2s;-webkit-animation-duration:calc(var(--animate-duration)*2);animation-duration:calc(var(--animate-duration)*2);-webkit-animation-name:hinge;animation-name:hinge;-webkit-transform-origin:top left;transform-origin:top left}@-webkit-keyframes jackInTheBox{0%{opacity:0;-webkit-transform:scale(.1) rotate(30deg);transform:scale(.1) rotate(30deg);-webkit-transform-origin:center bottom;transform-origin:center bottom}50%{-webkit-transform:rotate(-10deg);transform:rotate(-10deg)}70%{-webkit-transform:rotate(3deg);transform:rotate(3deg)}to{opacity:1;-webkit-transform:scale(1);transform:scale(1)}}@keyframes jackInTheBox{0%{opacity:0;-webkit-transform:scale(.1) rotate(30deg);transform:scale(.1) rotate(30deg);-webkit-transform-origin:center bottom;transform-origin:center bottom}50%{-webkit-transform:rotate(-10deg);transform:rotate(-10deg)}70%{-webkit-transform:rotate(3deg);transform:rotate(3deg)}to{opacity:1;-webkit-transform:scale(1);transform:scale(1)}}.animate__jackInTheBox{-webkit-animation-name:jackInTheBox;animation-name:jackInTheBox}@-webkit-keyframes rollIn{0%{opacity:0;-webkit-transform:translate3d(-100%,0,0) rotate(-120deg);transform:translate3d(-100%,0,0) rotate(-120deg)}to{opacity:1;-webkit-transform:translateZ(0);transform:translateZ(0)}}@keyframes rollIn{0%{opacity:0;-webkit-transform:translate3d(-100%,0,0) rotate(-120deg);transform:translate3d(-100%,0,0) rotate(-120deg)}to{opacity:1;-webkit-transform:translateZ(0);transform:translateZ(0)}}.animate__rollIn{-webkit-animation-name:rollIn;animation-name:rollIn}@-webkit-keyframes rollOut{0%{opacity:1}to{opacity:0;-webkit-transform:translate3d(100%,0,0) rotate(120deg);transform:translate3d(100%,0,0) rotate(120deg)}}@keyframes rollOut{0%{opacity:1}to{opacity:0;-webkit-transform:translate3d(100%,0,0) rotate(120deg);transform:translate3d(100%,0,0) rotate(120deg)}}.animate__rollOut{-webkit-animation-name:rollOut;animation-name:rollOut}@-webkit-keyframes zoomIn{0%{opacity:0;-webkit-transform:scale3d(.3,.3,.3);transform:scale3d(.3,.3,.3)}50%{opacity:1}}@keyframes zoomIn{0%{opacity:0;-webkit-transform:scale3d(.3,.3,.3);transform:scale3d(.3,.3,.3)}50%{opacity:1}}.animate__zoomIn{-webkit-animation-name:zoomIn;animation-name:zoomIn}@-webkit-keyframes zoomInDown{0%{opacity:0;-webkit-transform:scale3d(.1,.1,.1) translate3d(0,-1000px,0);transform:scale3d(.1,.1,.1) translate3d(0,-1000px,0);-webkit-animation-timing-function:cubic-bezier(.55,.055,.675,.19);animation-timing-function:cubic-bezier(.55,.055,.675,.19)}60%{opacity:1;-webkit-transform:scale3d(.475,.475,.475) translate3d(0,60px,0);transform:scale3d(.475,.475,.475) translate3d(0,60px,0);-webkit-animation-timing-function:cubic-bezier(.175,.885,.32,1);animation-timing-function:cubic-bezier(.175,.885,.32,1)}}@keyframes zoomInDown{0%{opacity:0;-webkit-transform:scale3d(.1,.1,.1) translate3d(0,-1000px,0);transform:scale3d(.1,.1,.1) translate3d(0,-1000px,0);-webkit-animation-timing-function:cubic-bezier(.55,.055,.675,.19);animation-timing-function:cubic-bezier(.55,.055,.675,.19)}60%{opacity:1;-webkit-transform:scale3d(.475,.475,.475) translate3d(0,60px,0);transform:scale3d(.475,.475,.475) translate3d(0,60px,0);-webkit-animation-timing-function:cubic-bezier(.175,.885,.32,1);animation-timing-function:cubic-bezier(.175,.885,.32,1)}}.animate__zoomInDown{-webkit-animation-name:zoomInDown;animation-name:zoomInDown}@-webkit-keyframes zoomInLeft{0%{opacity:0;-webkit-transform:scale3d(.1,.1,.1) translate3d(-1000px,0,0);transform:scale3d(.1,.1,.1) translate3d(-1000px,0,0);-webkit-animation-timing-function:cubic-bezier(.55,.055,.675,.19);animation-timing-function:cubic-bezier(.55,.055,.675,.19)}60%{opacity:1;-webkit-transform:scale3d(.475,.475,.475) translate3d(10px,0,0);transform:scale3d(.475,.475,.475) translate3d(10px,0,0);-webkit-animation-timing-function:cubic-bezier(.175,.885,.32,1);animation-timing-function:cubic-bezier(.175,.885,.32,1)}}@keyframes zoomInLeft{0%{opacity:0;-webkit-transform:scale3d(.1,.1,.1) translate3d(-1000px,0,0);transform:scale3d(.1,.1,.1) translate3d(-1000px,0,0);-webkit-animation-timing-function:cubic-bezier(.55,.055,.675,.19);animation-timing-function:cubic-bezier(.55,.055,.675,.19)}60%{opacity:1;-webkit-transform:scale3d(.475,.475,.475) translate3d(10px,0,0);transform:scale3d(.475,.475,.475) translate3d(10px,0,0);-webkit-animation-timing-function:cubic-bezier(.175,.885,.32,1);animation-timing-function:cubic-bezier(.175,.885,.32,1)}}.animate__zoomInLeft{-webkit-animation-name:zoomInLeft;animation-name:zoomInLeft}@-webkit-keyframes zoomInRight{0%{opacity:0;-webkit-transform:scale3d(.1,.1,.1) translate3d(1000px,0,0);transform:scale3d(.1,.1,.1) translate3d(1000px,0,0);-webkit-animation-timing-function:cubic-bezier(.55,.055,.675,.19);animation-timing-function:cubic-bezier(.55,.055,.675,.19)}60%{opacity:1;-webkit-transform:scale3d(.475,.475,.475) translate3d(-10px,0,0);transform:scale3d(.475,.475,.475) translate3d(-10px,0,0);-webkit-animation-timing-function:cubic-bezier(.175,.885,.32,1);animation-timing-function:cubic-bezier(.175,.885,.32,1)}}@keyframes zoomInRight{0%{opacity:0;-webkit-transform:scale3d(.1,.1,.1) translate3d(1000px,0,0);transform:scale3d(.1,.1,.1) translate3d(1000px,0,0);-webkit-animation-timing-function:cubic-bezier(.55,.055,.675,.19);animation-timing-function:cubic-bezier(.55,.055,.675,.19)}60%{opacity:1;-webkit-transform:scale3d(.475,.475,.475) translate3d(-10px,0,0);transform:scale3d(.475,.475,.475) translate3d(-10px,0,0);-webkit-animation-timing-function:cubic-bezier(.175,.885,.32,1);animation-timing-function:cubic-bezier(.175,.885,.32,1)}}.animate__zoomInRight{-webkit-animation-name:zoomInRight;animation-name:zoomInRight}@-webkit-keyframes zoomInUp{0%{opacity:0;-webkit-transform:scale3d(.1,.1,.1) translate3d(0,1000px,0);transform:scale3d(.1,.1,.1) translate3d(0,1000px,0);-webkit-animation-timing-function:cubic-bezier(.55,.055,.675,.19);animation-timing-function:cubic-bezier(.55,.055,.675,.19)}60%{opacity:1;-webkit-transform:scale3d(.475,.475,.475) translate3d(0,-60px,0);transform:scale3d(.475,.475,.475) translate3d(0,-60px,0);-webkit-animation-timing-function:cubic-bezier(.175,.885,.32,1);animation-timing-function:cubic-bezier(.175,.885,.32,1)}}@keyframes zoomInUp{0%{opacity:0;-webkit-transform:scale3d(.1,.1,.1) translate3d(0,1000px,0);transform:scale3d(.1,.1,.1) translate3d(0,1000px,0);-webkit-animation-timing-function:cubic-bezier(.55,.055,.675,.19);animation-timing-function:cubic-bezier(.55,.055,.675,.19)}60%{opacity:1;-webkit-transform:scale3d(.475,.475,.475) translate3d(0,-60px,0);transform:scale3d(.475,.475,.475) translate3d(0,-60px,0);-webkit-animation-timing-function:cubic-bezier(.175,.885,.32,1);animation-timing-function:cubic-bezier(.175,.885,.32,1)}}.animate__zoomInUp{-webkit-animation-name:zoomInUp;animation-name:zoomInUp}@-webkit-keyframes zoomOut{0%{opacity:1}50%{opacity:0;-webkit-transform:scale3d(.3,.3,.3);transform:scale3d(.3,.3,.3)}to{opacity:0}}@keyframes zoomOut{0%{opacity:1}50%{opacity:0;-webkit-transform:scale3d(.3,.3,.3);transform:scale3d(.3,.3,.3)}to{opacity:0}}.animate__zoomOut{-webkit-animation-name:zoomOut;animation-name:zoomOut}@-webkit-keyframes zoomOutDown{40%{opacity:1;-webkit-transform:scale3d(.475,.475,.475) translate3d(0,-60px,0);transform:scale3d(.475,.475,.475) translate3d(0,-60px,0);-webkit-animation-timing-function:cubic-bezier(.55,.055,.675,.19);animation-timing-function:cubic-bezier(.55,.055,.675,.19)}to{opacity:0;-webkit-transform:scale3d(.1,.1,.1) translate3d(0,2000px,0);transform:scale3d(.1,.1,.1) translate3d(0,2000px,0);-webkit-animation-timing-function:cubic-bezier(.175,.885,.32,1);animation-timing-function:cubic-bezier(.175,.885,.32,1)}}@keyframes zoomOutDown{40%{opacity:1;-webkit-transform:scale3d(.475,.475,.475) translate3d(0,-60px,0);transform:scale3d(.475,.475,.475) translate3d(0,-60px,0);-webkit-animation-timing-function:cubic-bezier(.55,.055,.675,.19);animation-timing-function:cubic-bezier(.55,.055,.675,.19)}to{opacity:0;-webkit-transform:scale3d(.1,.1,.1) translate3d(0,2000px,0);transform:scale3d(.1,.1,.1) translate3d(0,2000px,0);-webkit-animation-timing-function:cubic-bezier(.175,.885,.32,1);animation-timing-function:cubic-bezier(.175,.885,.32,1)}}.animate__zoomOutDown{-webkit-animation-name:zoomOutDown;animation-name:zoomOutDown;-webkit-transform-origin:center bottom;transform-origin:center bottom}@-webkit-keyframes zoomOutLeft{40%{opacity:1;-webkit-transform:scale3d(.475,.475,.475) translate3d(42px,0,0);transform:scale3d(.475,.475,.475) translate3d(42px,0,0)}to{opacity:0;-webkit-transform:scale(.1) translate3d(-2000px,0,0);transform:scale(.1) translate3d(-2000px,0,0)}}@keyframes zoomOutLeft{40%{opacity:1;-webkit-transform:scale3d(.475,.475,.475) translate3d(42px,0,0);transform:scale3d(.475,.475,.475) translate3d(42px,0,0)}to{opacity:0;-webkit-transform:scale(.1) translate3d(-2000px,0,0);transform:scale(.1) translate3d(-2000px,0,0)}}.animate__zoomOutLeft{-webkit-animation-name:zoomOutLeft;animation-name:zoomOutLeft;-webkit-transform-origin:left center;transform-origin:left center}@-webkit-keyframes zoomOutRight{40%{opacity:1;-webkit-transform:scale3d(.475,.475,.475) translate3d(-42px,0,0);transform:scale3d(.475,.475,.475) translate3d(-42px,0,0)}to{opacity:0;-webkit-transform:scale(.1) translate3d(2000px,0,0);transform:scale(.1) translate3d(2000px,0,0)}}@keyframes zoomOutRight{40%{opacity:1;-webkit-transform:scale3d(.475,.475,.475) translate3d(-42px,0,0);transform:scale3d(.475,.475,.475) translate3d(-42px,0,0)}to{opacity:0;-webkit-transform:scale(.1) translate3d(2000px,0,0);transform:scale(.1) translate3d(2000px,0,0)}}.animate__zoomOutRight{-webkit-animation-name:zoomOutRight;animation-name:zoomOutRight;-webkit-transform-origin:right center;transform-origin:right center}@-webkit-keyframes zoomOutUp{40%{opacity:1;-webkit-transform:scale3d(.475,.475,.475) translate3d(0,60px,0);transform:scale3d(.475,.475,.475) translate3d(0,60px,0);-webkit-animation-timing-function:cubic-bezier(.55,.055,.675,.19);animation-timing-function:cubic-bezier(.55,.055,.675,.19)}to{opacity:0;-webkit-transform:scale3d(.1,.1,.1) translate3d(0,-2000px,0);transform:scale3d(.1,.1,.1) translate3d(0,-2000px,0);-webkit-animation-timing-function:cubic-bezier(.175,.885,.32,1);animation-timing-function:cubic-bezier(.175,.885,.32,1)}}@keyframes zoomOutUp{40%{opacity:1;-webkit-transform:scale3d(.475,.475,.475) translate3d(0,60px,0);transform:scale3d(.475,.475,.475) translate3d(0,60px,0);-webkit-animation-timing-function:cubic-bezier(.55,.055,.675,.19);animation-timing-function:cubic-bezier(.55,.055,.675,.19)}to{opacity:0;-webkit-transform:scale3d(.1,.1,.1) translate3d(0,-2000px,0);transform:scale3d(.1,.1,.1) translate3d(0,-2000px,0);-webkit-animation-timing-function:cubic-bezier(.175,.885,.32,1);animation-timing-function:cubic-bezier(.175,.885,.32,1)}}.animate__zoomOutUp{-webkit-animation-name:zoomOutUp;animation-name:zoomOutUp;-webkit-transform-origin:center bottom;transform-origin:center bottom}@-webkit-keyframes slideInDown{0%{-webkit-transform:translate3d(0,-100%,0);transform:translate3d(0,-100%,0);visibility:visible}to{-webkit-transform:translateZ(0);transform:translateZ(0)}}@keyframes slideInDown{0%{-webkit-transform:translate3d(0,-100%,0);transform:translate3d(0,-100%,0);visibility:visible}to{-webkit-transform:translateZ(0);transform:translateZ(0)}}.animate__slideInDown{-webkit-animation-name:slideInDown;animation-name:slideInDown}@-webkit-keyframes slideInLeft{0%{-webkit-transform:translate3d(-100%,0,0);transform:translate3d(-100%,0,0);visibility:visible}to{-webkit-transform:translateZ(0);transform:translateZ(0)}}@keyframes slideInLeft{0%{-webkit-transform:translate3d(-100%,0,0);transform:translate3d(-100%,0,0);visibility:visible}to{-webkit-transform:translateZ(0);transform:translateZ(0)}}.animate__slideInLeft{-webkit-animation-name:slideInLeft;animation-name:slideInLeft}@-webkit-keyframes slideInRight{0%{-webkit-transform:translate3d(100%,0,0);transform:translate3d(100%,0,0);visibility:visible}to{-webkit-transform:translateZ(0);transform:translateZ(0)}}@keyframes slideInRight{0%{-webkit-transform:translate3d(100%,0,0);transform:translate3d(100%,0,0);visibility:visible}to{-webkit-transform:translateZ(0);transform:translateZ(0)}}.animate__slideInRight{-webkit-animation-name:slideInRight;animation-name:slideInRight}@-webkit-keyframes slideInUp{0%{-webkit-transform:translate3d(0,100%,0);transform:translate3d(0,100%,0);visibility:visible}to{-webkit-transform:translateZ(0);transform:translateZ(0)}}@keyframes slideInUp{0%{-webkit-transform:translate3d(0,100%,0);transform:translate3d(0,100%,0);visibility:visible}to{-webkit-transform:translateZ(0);transform:translateZ(0)}}.animate__slideInUp{-webkit-animation-name:slideInUp;animation-name:slideInUp}@-webkit-keyframes slideOutDown{0%{-webkit-transform:translateZ(0);transform:translateZ(0)}to{visibility:hidden;-webkit-transform:translate3d(0,100%,0);transform:translate3d(0,100%,0)}}@keyframes slideOutDown{0%{-webkit-transform:translateZ(0);transform:translateZ(0)}to{visibility:hidden;-webkit-transform:translate3d(0,100%,0);transform:translate3d(0,100%,0)}}.animate__slideOutDown{-webkit-animation-name:slideOutDown;animation-name:slideOutDown}@-webkit-keyframes slideOutLeft{0%{-webkit-transform:translateZ(0);transform:translateZ(0)}to{visibility:hidden;-webkit-transform:translate3d(-100%,0,0);transform:translate3d(-100%,0,0)}}@keyframes slideOutLeft{0%{-webkit-transform:translateZ(0);transform:translateZ(0)}to{visibility:hidden;-webkit-transform:translate3d(-100%,0,0);transform:translate3d(-100%,0,0)}}.animate__slideOutLeft{-webkit-animation-name:slideOutLeft;animation-name:slideOutLeft}@-webkit-keyframes slideOutRight{0%{-webkit-transform:translateZ(0);transform:translateZ(0)}to{visibility:hidden;-webkit-transform:translate3d(100%,0,0);transform:translate3d(100%,0,0)}}@keyframes slideOutRight{0%{-webkit-transform:translateZ(0);transform:translateZ(0)}to{visibility:hidden;-webkit-transform:translate3d(100%,0,0);transform:translate3d(100%,0,0)}}.animate__slideOutRight{-webkit-animation-name:slideOutRight;animation-name:slideOutRight}@-webkit-keyframes slideOutUp{0%{-webkit-transform:translateZ(0);transform:translateZ(0)}to{visibility:hidden;-webkit-transform:translate3d(0,-100%,0);transform:translate3d(0,-100%,0)}}@keyframes slideOutUp{0%{-webkit-transform:translateZ(0);transform:translateZ(0)}to{visibility:hidden;-webkit-transform:translate3d(0,-100%,0);transform:translate3d(0,-100%,0)}}.animate__slideOutUp{-webkit-animation-name:slideOutUp;animation-name:slideOutUp}
\ No newline at end of file
diff --git a/procentric/application/css/owlcarousel/owl.carousel.css b/procentric/application/css/owlcarousel/owl.carousel.css
new file mode 100755
index 0000000..40237bc
--- /dev/null
+++ b/procentric/application/css/owlcarousel/owl.carousel.css
@@ -0,0 +1,186 @@
+/**
+ * Owl Carousel v2.3.4
+ * Copyright 2013-2018 David Deutsch
+ * Licensed under: SEE LICENSE IN https://github.com/OwlCarousel2/OwlCarousel2/blob/master/LICENSE
+ */
+/*
+ * Owl Carousel - Core
+ */
+.owl-carousel {
+ display: none;
+ width: 100%;
+ -webkit-tap-highlight-color: transparent;
+ /* position relative and z-index fix webkit rendering fonts issue */
+ position: relative;
+ z-index: 1; }
+ .owl-carousel .owl-stage {
+ position: relative;
+ -ms-touch-action: pan-Y;
+ touch-action: manipulation;
+ -moz-backface-visibility: hidden;
+ /* fix firefox animation glitch */ }
+ .owl-carousel .owl-stage:after {
+ content: ".";
+ display: block;
+ clear: both;
+ visibility: hidden;
+ line-height: 0;
+ height: 0; }
+ .owl-carousel .owl-stage-outer {
+ position: relative;
+ overflow: hidden;
+ /* fix for flashing background */
+ -webkit-transform: translate3d(0px, 0px, 0px); }
+ .owl-carousel .owl-wrapper,
+ .owl-carousel .owl-item {
+ -webkit-backface-visibility: hidden;
+ -moz-backface-visibility: hidden;
+ -ms-backface-visibility: hidden;
+ -webkit-transform: translate3d(0, 0, 0);
+ -moz-transform: translate3d(0, 0, 0);
+ -ms-transform: translate3d(0, 0, 0); }
+ .owl-carousel .owl-item {
+ position: relative;
+ min-height: 1px;
+ float: left;
+ -webkit-backface-visibility: hidden;
+ -webkit-tap-highlight-color: transparent;
+ -webkit-touch-callout: none; }
+ .owl-carousel .owl-item img {
+ display: block;
+ width: 100%; }
+ .owl-carousel .owl-nav.disabled,
+ .owl-carousel .owl-dots.disabled {
+ display: none; }
+ .owl-carousel .owl-nav .owl-prev,
+ .owl-carousel .owl-nav .owl-next,
+ .owl-carousel .owl-dot {
+ cursor: pointer;
+ -webkit-user-select: none;
+ -khtml-user-select: none;
+ -moz-user-select: none;
+ -ms-user-select: none;
+ user-select: none; }
+ .owl-carousel .owl-nav button.owl-prev,
+ .owl-carousel .owl-nav button.owl-next,
+ .owl-carousel button.owl-dot {
+ background: none;
+ color: inherit;
+ border: none;
+ padding: 0 !important;
+ font: inherit; }
+ .owl-carousel.owl-loaded {
+ display: block; }
+ .owl-carousel.owl-loading {
+ opacity: 0;
+ display: block; }
+ .owl-carousel.owl-hidden {
+ opacity: 0; }
+ .owl-carousel.owl-refresh .owl-item {
+ visibility: hidden; }
+ .owl-carousel.owl-drag .owl-item {
+ -ms-touch-action: pan-y;
+ touch-action: pan-y;
+ -webkit-user-select: none;
+ -moz-user-select: none;
+ -ms-user-select: none;
+ user-select: none; }
+ .owl-carousel.owl-grab {
+ cursor: move;
+ cursor: grab; }
+ .owl-carousel.owl-rtl {
+ direction: rtl; }
+ .owl-carousel.owl-rtl .owl-item {
+ float: right; }
+
+/* No Js */
+.no-js .owl-carousel {
+ display: block; }
+
+/*
+ * Owl Carousel - Animate Plugin
+ */
+.owl-carousel .animated {
+ animation-duration: 1000ms;
+ animation-fill-mode: both; }
+
+.owl-carousel .owl-animated-in {
+ z-index: 0; }
+
+.owl-carousel .owl-animated-out {
+ z-index: 1; }
+
+.owl-carousel .fadeOut {
+ animation-name: fadeOut; }
+
+@keyframes fadeOut {
+ 0% {
+ opacity: 1; }
+ 100% {
+ opacity: 0; } }
+
+/*
+ * Owl Carousel - Auto Height Plugin
+ */
+.owl-height {
+ transition: height 500ms ease-in-out; }
+
+/*
+ * Owl Carousel - Lazy Load Plugin
+ */
+.owl-carousel .owl-item {
+ /**
+ This is introduced due to a bug in IE11 where lazy loading combined with autoheight plugin causes a wrong
+ calculation of the height of the owl-item that breaks page layouts
+ */ }
+ .owl-carousel .owl-item .owl-lazy {
+ opacity: 0;
+ transition: opacity 400ms ease; }
+ .owl-carousel .owl-item .owl-lazy[src^=""], .owl-carousel .owl-item .owl-lazy:not([src]) {
+ max-height: 0; }
+ .owl-carousel .owl-item img.owl-lazy {
+ transform-style: preserve-3d; }
+
+/*
+ * Owl Carousel - Video Plugin
+ */
+.owl-carousel .owl-video-wrapper {
+ position: relative;
+ height: 100%;
+ background: #000; }
+
+.owl-carousel .owl-video-play-icon {
+ position: absolute;
+ height: 80px;
+ width: 80px;
+ left: 50%;
+ top: 50%;
+ margin-left: -40px;
+ margin-top: -40px;
+ background: url("owl.video.play.png") no-repeat;
+ cursor: pointer;
+ z-index: 1;
+ -webkit-backface-visibility: hidden;
+ transition: transform 100ms ease; }
+
+.owl-carousel .owl-video-play-icon:hover {
+ -ms-transform: scale(1.3, 1.3);
+ transform: scale(1.3, 1.3); }
+
+.owl-carousel .owl-video-playing .owl-video-tn,
+.owl-carousel .owl-video-playing .owl-video-play-icon {
+ display: none; }
+
+.owl-carousel .owl-video-tn {
+ opacity: 0;
+ height: 100%;
+ background-position: center center;
+ background-repeat: no-repeat;
+ background-size: contain;
+ transition: opacity 400ms ease; }
+
+.owl-carousel .owl-video-frame {
+ position: relative;
+ z-index: 1;
+ height: 100%;
+ width: 100%; }
diff --git a/procentric/application/css/owlcarousel/owl.carousel.min.css b/procentric/application/css/owlcarousel/owl.carousel.min.css
new file mode 100755
index 0000000..ce6f6ff
--- /dev/null
+++ b/procentric/application/css/owlcarousel/owl.carousel.min.css
@@ -0,0 +1,218 @@
+/**
+ * Owl Carousel v2.3.4
+ * Copyright 2013-2018 David Deutsch
+ * Licensed under: SEE LICENSE IN https://github.com/OwlCarousel2/OwlCarousel2/blob/master/LICENSE
+ */
+
+.owl-carousel,
+.owl-carousel .owl-item {
+ -webkit-tap-highlight-color: transparent;
+ position: relative
+}
+
+.owl-carousel {
+ display: none;
+ width: 100%;
+ z-index: 1
+}
+
+.owl-carousel .owl-stage {
+ position: relative;
+ -ms-touch-action: pan-Y;
+ touch-action: manipulation;
+ -moz-backface-visibility: hidden
+}
+
+.owl-carousel .owl-stage:after {
+ content: ".";
+ display: block;
+ clear: both;
+ visibility: hidden;
+ line-height: 0;
+ height: 0
+}
+
+.owl-carousel .owl-stage-outer {
+ position: relative;
+ overflow: hidden;
+ -webkit-transform: translate3d(0, 0, 0)
+}
+
+.owl-carousel .owl-item,
+.owl-carousel .owl-wrapper {
+ -webkit-backface-visibility: hidden;
+ -moz-backface-visibility: hidden;
+ -ms-backface-visibility: hidden;
+ -webkit-transform: translate3d(0, 0, 0);
+ -moz-transform: translate3d(0, 0, 0);
+ -ms-transform: translate3d(0, 0, 0)
+}
+
+.owl-carousel .owl-item {
+ min-height: 1px;
+ float: left;
+ -webkit-backface-visibility: hidden;
+ -webkit-touch-callout: none
+}
+
+.owl-carousel .owl-item img {
+ display: block;
+ width: 100%
+}
+
+.owl-carousel .owl-dots.disabled,
+.owl-carousel .owl-nav.disabled {
+ display: none
+}
+
+.no-js .owl-carousel,
+.owl-carousel.owl-loaded {
+ display: block
+}
+
+.owl-carousel .owl-dot,
+.owl-carousel .owl-nav .owl-next,
+.owl-carousel .owl-nav .owl-prev {
+ cursor: pointer;
+ -webkit-user-select: none;
+ -khtml-user-select: none;
+ -moz-user-select: none;
+ -ms-user-select: none;
+ user-select: none
+}
+
+.owl-carousel .owl-nav button.owl-next,
+.owl-carousel .owl-nav button.owl-prev,
+.owl-carousel button.owl-dot {
+ background: 0 0;
+ color: inherit;
+ border: none;
+ padding: 0!important;
+ font: inherit
+}
+
+.owl-carousel.owl-loading {
+ opacity: 0;
+ display: block
+}
+
+.owl-carousel.owl-hidden {
+ opacity: 0
+}
+
+.owl-carousel.owl-refresh .owl-item {
+ visibility: hidden
+}
+
+.owl-carousel.owl-drag .owl-item {
+ -ms-touch-action: pan-y;
+ touch-action: pan-y;
+ -webkit-user-select: none;
+ -moz-user-select: none;
+ -ms-user-select: none;
+ user-select: none
+}
+
+.owl-carousel.owl-grab {
+ cursor: move;
+ cursor: grab
+}
+
+.owl-carousel.owl-rtl {
+ direction: rtl
+}
+
+.owl-carousel.owl-rtl .owl-item {
+ float: right
+}
+
+.owl-carousel .animated {
+ animation-duration: 1s;
+ animation-fill-mode: both
+}
+
+.owl-carousel .owl-animated-in {
+ z-index: 0
+}
+
+.owl-carousel .owl-animated-out {
+ z-index: 1
+}
+
+.owl-carousel .fadeOut {
+ animation-name: fadeOut
+}
+
+@keyframes fadeOut {
+ 0% {
+ opacity: 1
+ }
+ 100% {
+ opacity: 0
+ }
+}
+
+.owl-height {
+ transition: height .5s ease-in-out
+}
+
+.owl-carousel .owl-item .owl-lazy {
+ opacity: 0;
+ transition: opacity .4s ease
+}
+
+.owl-carousel .owl-item .owl-lazy:not([src]),
+.owl-carousel .owl-item .owl-lazy[src^=""] {
+ max-height: 0
+}
+
+.owl-carousel .owl-item img.owl-lazy {
+ transform-style: preserve-3d
+}
+
+.owl-carousel .owl-video-wrapper {
+ position: relative;
+ height: 100%;
+ background: #000
+}
+
+.owl-carousel .owl-video-play-icon {
+ position: absolute;
+ height: 80px;
+ width: 80px;
+ left: 50%;
+ top: 50%;
+ margin-left: -40px;
+ margin-top: -40px;
+ background: url(owl.video.play.png) no-repeat;
+ cursor: pointer;
+ z-index: 1;
+ -webkit-backface-visibility: hidden;
+ transition: transform .1s ease
+}
+
+.owl-carousel .owl-video-play-icon:hover {
+ -ms-transform: scale(1.3, 1.3);
+ transform: scale(1.3, 1.3)
+}
+
+.owl-carousel .owl-video-playing .owl-video-play-icon,
+.owl-carousel .owl-video-playing .owl-video-tn {
+ display: none
+}
+
+.owl-carousel .owl-video-tn {
+ opacity: 0;
+ height: 100%;
+ background-position: center center;
+ background-repeat: no-repeat;
+ background-size: contain;
+ transition: opacity .4s ease
+}
+
+.owl-carousel .owl-video-frame {
+ position: relative;
+ z-index: 1;
+ height: 100%;
+ width: 100%
+}
\ No newline at end of file
diff --git a/procentric/application/css/owlcarousel/owl.theme.default.css b/procentric/application/css/owlcarousel/owl.theme.default.css
new file mode 100755
index 0000000..e2020fb
--- /dev/null
+++ b/procentric/application/css/owlcarousel/owl.theme.default.css
@@ -0,0 +1,50 @@
+/**
+ * Owl Carousel v2.3.4
+ * Copyright 2013-2018 David Deutsch
+ * Licensed under: SEE LICENSE IN https://github.com/OwlCarousel2/OwlCarousel2/blob/master/LICENSE
+ */
+/*
+ * Default theme - Owl Carousel CSS File
+ */
+.owl-theme .owl-nav {
+ margin-top: 10px;
+ text-align: center;
+ -webkit-tap-highlight-color: transparent; }
+ .owl-theme .owl-nav [class*='owl-'] {
+ color: #FFF;
+ font-size: 14px;
+ margin: 5px;
+ padding: 4px 7px;
+ background: #D6D6D6;
+ display: inline-block;
+ cursor: pointer;
+ border-radius: 3px; }
+ .owl-theme .owl-nav [class*='owl-']:hover {
+ background: #869791;
+ color: #FFF;
+ text-decoration: none; }
+ .owl-theme .owl-nav .disabled {
+ opacity: 0.5;
+ cursor: default; }
+
+.owl-theme .owl-nav.disabled + .owl-dots {
+ margin-top: 10px; }
+
+.owl-theme .owl-dots {
+ text-align: center;
+ -webkit-tap-highlight-color: transparent; }
+ .owl-theme .owl-dots .owl-dot {
+ display: inline-block;
+ zoom: 1;
+ *display: inline; }
+ .owl-theme .owl-dots .owl-dot span {
+ width: 10px;
+ height: 10px;
+ margin: 5px 7px;
+ background: #D6D6D6;
+ display: block;
+ -webkit-backface-visibility: visible;
+ transition: opacity 200ms ease;
+ border-radius: 30px; }
+ .owl-theme .owl-dots .owl-dot.active span, .owl-theme .owl-dots .owl-dot:hover span {
+ background: #869791; }
diff --git a/procentric/application/css/owlcarousel/owl.theme.default.min.css b/procentric/application/css/owlcarousel/owl.theme.default.min.css
new file mode 100755
index 0000000..c2f4f72
--- /dev/null
+++ b/procentric/application/css/owlcarousel/owl.theme.default.min.css
@@ -0,0 +1,65 @@
+/**
+ * Owl Carousel v2.3.4
+ * Copyright 2013-2018 David Deutsch
+ * Licensed under: SEE LICENSE IN https://github.com/OwlCarousel2/OwlCarousel2/blob/master/LICENSE
+ */
+
+.owl-theme .owl-dots,
+.owl-theme .owl-nav {
+ text-align: center;
+ -webkit-tap-highlight-color: transparent
+}
+
+.owl-theme .owl-nav {
+ margin-top: 10px
+}
+
+.owl-theme .owl-nav [class*=owl-] {
+ color: #FFF;
+ font-size: 14px;
+ margin: 5px;
+ padding: 4px 7px;
+ background: #D6D6D6;
+ display: inline-block;
+ cursor: pointer;
+ border-radius: 3px
+}
+
+.owl-theme .owl-nav [class*=owl-]:hover {
+ background: #869791;
+ color: #FFF;
+ text-decoration: none
+}
+
+.owl-theme .owl-nav .disabled {
+ opacity: .5;
+ cursor: default
+}
+
+.owl-theme .owl-nav.disabled+.owl-dots {
+ margin-top: 10px
+}
+
+.owl-theme .owl-dots .owl-dot {
+ display: inline-block;
+ zoom: 1
+}
+
+.owl-theme .owl-dots .owl-dot span {
+ width: 24px;
+ height: 14px;
+ margin: 5px 5px;
+ background: #D6D6D6;
+ display: block;
+ -webkit-backface-visibility: visible;
+ transition: opacity .2s ease;
+ border: 2px solid rgb(80, 80, 80);
+ filter: drop-shadow(0 1px 2px rgb(0, 0, 0));
+ border-radius: 30px;
+}
+
+.owl-theme .owl-dots .owl-dot.active span,
+.owl-theme .owl-dots .owl-dot:hover span {
+ background: rgb(181, 218, 16);
+ border: 2px solid rgb(10, 10, 10);
+}
\ No newline at end of file
diff --git a/procentric/application/css/owlcarousel/owl.theme.green.css b/procentric/application/css/owlcarousel/owl.theme.green.css
new file mode 100755
index 0000000..5235fbe
--- /dev/null
+++ b/procentric/application/css/owlcarousel/owl.theme.green.css
@@ -0,0 +1,50 @@
+/**
+ * Owl Carousel v2.3.4
+ * Copyright 2013-2018 David Deutsch
+ * Licensed under: SEE LICENSE IN https://github.com/OwlCarousel2/OwlCarousel2/blob/master/LICENSE
+ */
+/*
+ * Green theme - Owl Carousel CSS File
+ */
+.owl-theme .owl-nav {
+ margin-top: 10px;
+ text-align: center;
+ -webkit-tap-highlight-color: transparent; }
+ .owl-theme .owl-nav [class*='owl-'] {
+ color: #FFF;
+ font-size: 14px;
+ margin: 5px;
+ padding: 4px 7px;
+ background: #D6D6D6;
+ display: inline-block;
+ cursor: pointer;
+ border-radius: 3px; }
+ .owl-theme .owl-nav [class*='owl-']:hover {
+ background: #4DC7A0;
+ color: #FFF;
+ text-decoration: none; }
+ .owl-theme .owl-nav .disabled {
+ opacity: 0.5;
+ cursor: default; }
+
+.owl-theme .owl-nav.disabled + .owl-dots {
+ margin-top: 10px; }
+
+.owl-theme .owl-dots {
+ text-align: center;
+ -webkit-tap-highlight-color: transparent; }
+ .owl-theme .owl-dots .owl-dot {
+ display: inline-block;
+ zoom: 1;
+ *display: inline; }
+ .owl-theme .owl-dots .owl-dot span {
+ width: 10px;
+ height: 10px;
+ margin: 5px 7px;
+ background: #D6D6D6;
+ display: block;
+ -webkit-backface-visibility: visible;
+ transition: opacity 200ms ease;
+ border-radius: 30px; }
+ .owl-theme .owl-dots .owl-dot.active span, .owl-theme .owl-dots .owl-dot:hover span {
+ background: #4DC7A0; }
diff --git a/procentric/application/css/owlcarousel/owl.theme.green.min.css b/procentric/application/css/owlcarousel/owl.theme.green.min.css
new file mode 100755
index 0000000..187bea0
--- /dev/null
+++ b/procentric/application/css/owlcarousel/owl.theme.green.min.css
@@ -0,0 +1,6 @@
+/**
+ * Owl Carousel v2.3.4
+ * Copyright 2013-2018 David Deutsch
+ * Licensed under: SEE LICENSE IN https://github.com/OwlCarousel2/OwlCarousel2/blob/master/LICENSE
+ */
+.owl-theme .owl-dots,.owl-theme .owl-nav{text-align:center;-webkit-tap-highlight-color:transparent}.owl-theme .owl-nav{margin-top:10px}.owl-theme .owl-nav [class*=owl-]{color:#FFF;font-size:14px;margin:5px;padding:4px 7px;background:#D6D6D6;display:inline-block;cursor:pointer;border-radius:3px}.owl-theme .owl-nav [class*=owl-]:hover{background:#4DC7A0;color:#FFF;text-decoration:none}.owl-theme .owl-nav .disabled{opacity:.5;cursor:default}.owl-theme .owl-nav.disabled+.owl-dots{margin-top:10px}.owl-theme .owl-dots .owl-dot{display:inline-block;zoom:1}.owl-theme .owl-dots .owl-dot span{width:10px;height:10px;margin:5px 7px;background:#D6D6D6;display:block;-webkit-backface-visibility:visible;transition:opacity .2s ease;border-radius:30px}.owl-theme .owl-dots .owl-dot.active span,.owl-theme .owl-dots .owl-dot:hover span{background:#4DC7A0}
\ No newline at end of file
diff --git a/procentric/application/css/owlcarousel/owl.video.play.png b/procentric/application/css/owlcarousel/owl.video.play.png
new file mode 100755
index 0000000..5d0218d
Binary files /dev/null and b/procentric/application/css/owlcarousel/owl.video.play.png differ
diff --git a/procentric/application/css/tiny-slider.css b/procentric/application/css/tiny-slider.css
new file mode 100755
index 0000000..505efce
--- /dev/null
+++ b/procentric/application/css/tiny-slider.css
@@ -0,0 +1,105 @@
+[data-tns-role="wrapper"] {
+ padding: 0 !important
+}
+
+[data-tns-role="wrapper"].ms-touch {
+ overflow-x: scroll;
+ overflow-y: hidden;
+ -ms-overflow-style: none;
+ -ms-scroll-chaining: none;
+ -ms-scroll-snap-type: mandatory;
+ -ms-scroll-snap-points-x: snapInterval(0%, 100%)
+}
+
+[data-tns-role="content"] {
+ position: relative;
+ -webkit-transition: all 0s;
+ -moz-transition: all 0s;
+ transition: all 0s
+}
+
+[data-tns-mode="carousel"][data-tns-axis="horizontal"] {
+ white-space: nowrap;
+ left: 0
+}
+
+[data-tns-mode="carousel"][data-tns-axis="horizontal"]:after {
+ content: '';
+ display: table;
+ clear: both
+}
+
+[data-tns-mode="carousel"][data-tns-axis="horizontal"]>div,
+[data-tns-mode="carousel"][data-tns-axis="horizontal"]>li,
+[data-tns-mode="carousel"][data-tns-axis="horizontal"]>span,
+[data-tns-mode="carousel"][data-tns-axis="horizontal"]>a {
+ display: inline-block;
+ vertical-align: top;
+ white-space: normal;
+ -webkit-box-sizing: border-box;
+ -moz-box-sizing: border-box;
+ box-sizing: border-box;
+ overflow: hidden
+}
+
+[data-tns-mode="gallery"] {
+ overflow: hidden
+}
+
+[data-tns-mode="gallery"]>div,
+[data-tns-mode="gallery"]>li,
+[data-tns-mode="gallery"]>span,
+[data-tns-mode="gallery"]>a {
+ position: absolute;
+ -webkit-transition: transform 0s, opacity 0s;
+ -moz-transition: transform 0s, opacity 0s;
+ transition: transform 0s, opacity 0s
+}
+
+[data-tns-role="nav"] button {
+ vertical-align: middle
+}
+
+[data-tns-role="lazy-img"] {
+ -webkit-transition: opacity 0.6s;
+ -moz-transition: opacity 0.6s;
+ transition: opacity 0.6s;
+ opacity: 0.6
+}
+
+[data-tns-role="lazy-img"].loaded {
+ opacity: 1
+}
+
+[hidden] {
+ display: none !important
+}
+
+[data-controls],
+[data-action],
+[data-nav] {
+ cursor: pointer;
+ border-width: 0;
+ padding: 0
+}
+
+[data-tns-hidden="x"] {
+ overflow-x: hidden
+}
+
+[data-tns-hidden="y"] {
+ overflow-y: hidden
+}
+
+.tns-fadeIn {
+ opacity: 1;
+ filter: alpha(opacity=100);
+ z-index: 0
+}
+
+.tns-normal,
+.tns-fadeOut {
+ opacity: 0;
+ filter: alpha(opacity=0);
+ z-index: -1
+}
\ No newline at end of file
diff --git a/procentric/application/fonts/Ma_Shan_Zheng/MaShanZheng-Regular.ttf b/procentric/application/fonts/Ma_Shan_Zheng/MaShanZheng-Regular.ttf
new file mode 100755
index 0000000..400499d
Binary files /dev/null and b/procentric/application/fonts/Ma_Shan_Zheng/MaShanZheng-Regular.ttf differ
diff --git a/procentric/application/fonts/Ma_Shan_Zheng/OFL.txt b/procentric/application/fonts/Ma_Shan_Zheng/OFL.txt
new file mode 100755
index 0000000..21b16f5
--- /dev/null
+++ b/procentric/application/fonts/Ma_Shan_Zheng/OFL.txt
@@ -0,0 +1,93 @@
+Copyright 2018 The Ma Shan Zheng Project Authors (https://github.com/googlefonts/mashanzheng)
+
+This Font Software is licensed under the SIL Open Font License, Version 1.1.
+This license is copied below, and is also available with a FAQ at:
+http://scripts.sil.org/OFL
+
+
+-----------------------------------------------------------
+SIL OPEN FONT LICENSE Version 1.1 - 26 February 2007
+-----------------------------------------------------------
+
+PREAMBLE
+The goals of the Open Font License (OFL) are to stimulate worldwide
+development of collaborative font projects, to support the font creation
+efforts of academic and linguistic communities, and to provide a free and
+open framework in which fonts may be shared and improved in partnership
+with others.
+
+The OFL allows the licensed fonts to be used, studied, modified and
+redistributed freely as long as they are not sold by themselves. The
+fonts, including any derivative works, can be bundled, embedded,
+redistributed and/or sold with any software provided that any reserved
+names are not used by derivative works. The fonts and derivatives,
+however, cannot be released under any other type of license. The
+requirement for fonts to remain under this license does not apply
+to any document created using the fonts or their derivatives.
+
+DEFINITIONS
+"Font Software" refers to the set of files released by the Copyright
+Holder(s) under this license and clearly marked as such. This may
+include source files, build scripts and documentation.
+
+"Reserved Font Name" refers to any names specified as such after the
+copyright statement(s).
+
+"Original Version" refers to the collection of Font Software components as
+distributed by the Copyright Holder(s).
+
+"Modified Version" refers to any derivative made by adding to, deleting,
+or substituting -- in part or in whole -- any of the components of the
+Original Version, by changing formats or by porting the Font Software to a
+new environment.
+
+"Author" refers to any designer, engineer, programmer, technical
+writer or other person who contributed to the Font Software.
+
+PERMISSION & CONDITIONS
+Permission is hereby granted, free of charge, to any person obtaining
+a copy of the Font Software, to use, study, copy, merge, embed, modify,
+redistribute, and sell modified and unmodified copies of the Font
+Software, subject to the following conditions:
+
+1) Neither the Font Software nor any of its individual components,
+in Original or Modified Versions, may be sold by itself.
+
+2) Original or Modified Versions of the Font Software may be bundled,
+redistributed and/or sold with any software, provided that each copy
+contains the above copyright notice and this license. These can be
+included either as stand-alone text files, human-readable headers or
+in the appropriate machine-readable metadata fields within text or
+binary files as long as those fields can be easily viewed by the user.
+
+3) No Modified Version of the Font Software may use the Reserved Font
+Name(s) unless explicit written permission is granted by the corresponding
+Copyright Holder. This restriction only applies to the primary font name as
+presented to the users.
+
+4) The name(s) of the Copyright Holder(s) or the Author(s) of the Font
+Software shall not be used to promote, endorse or advertise any
+Modified Version, except to acknowledge the contribution(s) of the
+Copyright Holder(s) and the Author(s) or with their explicit written
+permission.
+
+5) The Font Software, modified or unmodified, in part or in whole,
+must be distributed entirely under this license, and must not be
+distributed under any other license. The requirement for fonts to
+remain under this license does not apply to any document created
+using the Font Software.
+
+TERMINATION
+This license becomes null and void if any of the above conditions are
+not met.
+
+DISCLAIMER
+THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT
+OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL THE
+COPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL
+DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+FROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM
+OTHER DEALINGS IN THE FONT SOFTWARE.
diff --git a/procentric/application/fonts/Nanum_Pen_Script/NanumPenScript-Regular.ttf b/procentric/application/fonts/Nanum_Pen_Script/NanumPenScript-Regular.ttf
new file mode 100755
index 0000000..8473a19
Binary files /dev/null and b/procentric/application/fonts/Nanum_Pen_Script/NanumPenScript-Regular.ttf differ
diff --git a/procentric/application/fonts/Nanum_Pen_Script/OFL.txt b/procentric/application/fonts/Nanum_Pen_Script/OFL.txt
new file mode 100755
index 0000000..c823aeb
--- /dev/null
+++ b/procentric/application/fonts/Nanum_Pen_Script/OFL.txt
@@ -0,0 +1,97 @@
+Copyright (c) 2010, NHN Corporation (http://www.nhncorp.com),
+with Reserved Font Name Nanum, Naver Nanum, NanumGothic, Naver
+NanumGothic, NanumMyeongjo, Naver NanumMyeongjo, NanumBrush, Naver
+NanumBrush, NanumPen, Naver NanumPen.
+
+
+This Font Software is licensed under the SIL Open Font License, Version 1.1.
+This license is copied below, and is also available with a FAQ at:
+http://scripts.sil.org/OFL
+
+
+-----------------------------------------------------------
+SIL OPEN FONT LICENSE Version 1.1 - 26 February 2007
+-----------------------------------------------------------
+
+PREAMBLE
+The goals of the Open Font License (OFL) are to stimulate worldwide
+development of collaborative font projects, to support the font creation
+efforts of academic and linguistic communities, and to provide a free and
+open framework in which fonts may be shared and improved in partnership
+with others.
+
+The OFL allows the licensed fonts to be used, studied, modified and
+redistributed freely as long as they are not sold by themselves. The
+fonts, including any derivative works, can be bundled, embedded,
+redistributed and/or sold with any software provided that any reserved
+names are not used by derivative works. The fonts and derivatives,
+however, cannot be released under any other type of license. The
+requirement for fonts to remain under this license does not apply
+to any document created using the fonts or their derivatives.
+
+DEFINITIONS
+"Font Software" refers to the set of files released by the Copyright
+Holder(s) under this license and clearly marked as such. This may
+include source files, build scripts and documentation.
+
+"Reserved Font Name" refers to any names specified as such after the
+copyright statement(s).
+
+"Original Version" refers to the collection of Font Software components as
+distributed by the Copyright Holder(s).
+
+"Modified Version" refers to any derivative made by adding to, deleting,
+or substituting -- in part or in whole -- any of the components of the
+Original Version, by changing formats or by porting the Font Software to a
+new environment.
+
+"Author" refers to any designer, engineer, programmer, technical
+writer or other person who contributed to the Font Software.
+
+PERMISSION & CONDITIONS
+Permission is hereby granted, free of charge, to any person obtaining
+a copy of the Font Software, to use, study, copy, merge, embed, modify,
+redistribute, and sell modified and unmodified copies of the Font
+Software, subject to the following conditions:
+
+1) Neither the Font Software nor any of its individual components,
+in Original or Modified Versions, may be sold by itself.
+
+2) Original or Modified Versions of the Font Software may be bundled,
+redistributed and/or sold with any software, provided that each copy
+contains the above copyright notice and this license. These can be
+included either as stand-alone text files, human-readable headers or
+in the appropriate machine-readable metadata fields within text or
+binary files as long as those fields can be easily viewed by the user.
+
+3) No Modified Version of the Font Software may use the Reserved Font
+Name(s) unless explicit written permission is granted by the corresponding
+Copyright Holder. This restriction only applies to the primary font name as
+presented to the users.
+
+4) The name(s) of the Copyright Holder(s) or the Author(s) of the Font
+Software shall not be used to promote, endorse or advertise any
+Modified Version, except to acknowledge the contribution(s) of the
+Copyright Holder(s) and the Author(s) or with their explicit written
+permission.
+
+5) The Font Software, modified or unmodified, in part or in whole,
+must be distributed entirely under this license, and must not be
+distributed under any other license. The requirement for fonts to
+remain under this license does not apply to any document created
+using the Font Software.
+
+TERMINATION
+This license becomes null and void if any of the above conditions are
+not met.
+
+DISCLAIMER
+THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT
+OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL THE
+COPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL
+DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+FROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM
+OTHER DEALINGS IN THE FONT SOFTWARE.
diff --git a/procentric/application/fonts/Parisienne/OFL.txt b/procentric/application/fonts/Parisienne/OFL.txt
new file mode 100755
index 0000000..fd7a0cd
--- /dev/null
+++ b/procentric/application/fonts/Parisienne/OFL.txt
@@ -0,0 +1,94 @@
+Copyright (c) 2012 by Brian J. Bonislawsky DBA Astigmatic (AOETI)
+(astigma@astigmatic.com), with Reserved Font Names "Parisienne"
+
+This Font Software is licensed under the SIL Open Font License, Version 1.1.
+This license is copied below, and is also available with a FAQ at:
+http://scripts.sil.org/OFL
+
+
+-----------------------------------------------------------
+SIL OPEN FONT LICENSE Version 1.1 - 26 February 2007
+-----------------------------------------------------------
+
+PREAMBLE
+The goals of the Open Font License (OFL) are to stimulate worldwide
+development of collaborative font projects, to support the font creation
+efforts of academic and linguistic communities, and to provide a free and
+open framework in which fonts may be shared and improved in partnership
+with others.
+
+The OFL allows the licensed fonts to be used, studied, modified and
+redistributed freely as long as they are not sold by themselves. The
+fonts, including any derivative works, can be bundled, embedded,
+redistributed and/or sold with any software provided that any reserved
+names are not used by derivative works. The fonts and derivatives,
+however, cannot be released under any other type of license. The
+requirement for fonts to remain under this license does not apply
+to any document created using the fonts or their derivatives.
+
+DEFINITIONS
+"Font Software" refers to the set of files released by the Copyright
+Holder(s) under this license and clearly marked as such. This may
+include source files, build scripts and documentation.
+
+"Reserved Font Name" refers to any names specified as such after the
+copyright statement(s).
+
+"Original Version" refers to the collection of Font Software components as
+distributed by the Copyright Holder(s).
+
+"Modified Version" refers to any derivative made by adding to, deleting,
+or substituting -- in part or in whole -- any of the components of the
+Original Version, by changing formats or by porting the Font Software to a
+new environment.
+
+"Author" refers to any designer, engineer, programmer, technical
+writer or other person who contributed to the Font Software.
+
+PERMISSION & CONDITIONS
+Permission is hereby granted, free of charge, to any person obtaining
+a copy of the Font Software, to use, study, copy, merge, embed, modify,
+redistribute, and sell modified and unmodified copies of the Font
+Software, subject to the following conditions:
+
+1) Neither the Font Software nor any of its individual components,
+in Original or Modified Versions, may be sold by itself.
+
+2) Original or Modified Versions of the Font Software may be bundled,
+redistributed and/or sold with any software, provided that each copy
+contains the above copyright notice and this license. These can be
+included either as stand-alone text files, human-readable headers or
+in the appropriate machine-readable metadata fields within text or
+binary files as long as those fields can be easily viewed by the user.
+
+3) No Modified Version of the Font Software may use the Reserved Font
+Name(s) unless explicit written permission is granted by the corresponding
+Copyright Holder. This restriction only applies to the primary font name as
+presented to the users.
+
+4) The name(s) of the Copyright Holder(s) or the Author(s) of the Font
+Software shall not be used to promote, endorse or advertise any
+Modified Version, except to acknowledge the contribution(s) of the
+Copyright Holder(s) and the Author(s) or with their explicit written
+permission.
+
+5) The Font Software, modified or unmodified, in part or in whole,
+must be distributed entirely under this license, and must not be
+distributed under any other license. The requirement for fonts to
+remain under this license does not apply to any document created
+using the Font Software.
+
+TERMINATION
+This license becomes null and void if any of the above conditions are
+not met.
+
+DISCLAIMER
+THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT
+OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL THE
+COPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL
+DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+FROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM
+OTHER DEALINGS IN THE FONT SOFTWARE.
diff --git a/procentric/application/fonts/Parisienne/Parisienne-Regular.ttf b/procentric/application/fonts/Parisienne/Parisienne-Regular.ttf
new file mode 100755
index 0000000..bbbaeda
Binary files /dev/null and b/procentric/application/fonts/Parisienne/Parisienne-Regular.ttf differ
diff --git a/procentric/application/hoteltv.app.full.css b/procentric/application/hoteltv.app.full.css
new file mode 100755
index 0000000..387b9b3
--- /dev/null
+++ b/procentric/application/hoteltv.app.full.css
@@ -0,0 +1,105 @@
+/* STEP[#001]: Define Main */
+
+.main {
+ position: absolute;
+ top: 0px;
+ left: 0px;
+ width: 1920px;
+ height: 1080px;
+ padding: 0px;
+ text-shadow: 0 0 10px rgba(38, 18, 18, 0.5), 0 0 10px rgba(65, 65, 65, 1);
+ z-index: 1;
+}
+
+.main ::-webkit-scrollbar {
+ display: none;
+}
+
+.control {
+ position: absolute;
+ top: 0px;
+ left: 0px;
+ width: 1920px;
+ height: 1080px;
+ margin: 0;
+ padding: 0;
+}
+
+.control .mm .hotkey_red {
+ position: absolute;
+ width: 360px;
+ height: 50px;
+ z-index: 1;
+ display: none;
+ line-height: 50px;
+ color: rgb(235, 235, 235);
+ padding-left: 80px;
+ font-size: 30px;
+ text-shadow: 2px 2px 2px rgba(26, 26, 26, 1);
+ /* filter: drop-shadow(0 0 5px rgb(0, 0, 0)); */
+ white-space: nowrap;
+ background-size: contain;
+ background-repeat: no-repeat;
+}
+
+.control .mm .hotkey_green {
+ position: absolute;
+ width: 360px;
+ height: 50px;
+ z-index: 1;
+ display: none;
+ line-height: 50px;
+ color: rgb(235, 235, 235);
+ padding-left: 80px;
+ font-size: 30px;
+ text-shadow: 2px 2px 2px rgba(26, 26, 26, 1);
+ /* filter: drop-shadow(0 0 5px rgb(0, 0, 0)); */
+ white-space: nowrap;
+ background-size: contain;
+ background-repeat: no-repeat;
+}
+
+.control .mm .hotkey_yellow {
+ position: absolute;
+ width: 360px;
+ height: 50px;
+ z-index: 1;
+ display: none;
+ line-height: 50px;
+ color: rgb(235, 235, 235);
+ padding-left: 80px;
+ font-size: 30px;
+ text-shadow: 2px 2px 2px rgba(26, 26, 26, 1);
+ /* filter: drop-shadow(0 0 5px rgb(0, 0, 0)); */
+ white-space: nowrap;
+ background-size: contain;
+ background-repeat: no-repeat;
+}
+
+.control .mm .hotkey_blue {
+ position: absolute;
+ width: 360px;
+ height: 50px;
+ z-index: 1;
+ display: none;
+ line-height: 50px;
+ color: rgb(235, 235, 235);
+ padding-left: 80px;
+ font-size: 30px;
+ text-shadow: 2px 2px 2px rgba(26, 26, 26, 1);
+ /* filter: drop-shadow(0 0 5px rgb(0, 0, 0)); */
+ white-space: nowrap;
+ background-size: contain;
+ background-repeat: no-repeat;
+}
+
+
+/* SETP[#003-4]: Player */
+
+.player {
+ position: absolute;
+ top: 0px;
+ left: 0px;
+ width: 1920px;
+ height: 1080px;
+}
\ No newline at end of file
diff --git a/procentric/application/hoteltv.app.full.ctzgen.css b/procentric/application/hoteltv.app.full.ctzgen.css
new file mode 100755
index 0000000..5d95fbb
--- /dev/null
+++ b/procentric/application/hoteltv.app.full.ctzgen.css
@@ -0,0 +1,254 @@
+.main .ctzgen {
+ position: absolute;
+ top: 2160px;
+ left: 0px;
+ width: 1920px;
+ height: 1080px;
+ background-image: url(tv:);
+ display: none;
+}
+
+.main .ctzgen .bg {
+ position: absolute;
+ top: 0px;
+ left: 0%;
+ width: 1920px;
+ height: 1080px;
+ padding: 0px;
+ overflow: hidden;
+ display: none;
+}
+
+.main .ctzgen .bg .owl-dots {
+ position: absolute;
+ top: 980px;
+ width: 100%;
+ align-content: center;
+}
+
+.main .ctzgen .bg div#lst_ctzgenbg {
+ position: absolute;
+ width: 1920px;
+ height: 1080px;
+ margin: 0;
+ padding: 0;
+}
+
+.main .ctzgen .bg .owl-carousel .owl-stage-outer {
+ width: 1920px;
+ height: 1080px;
+ margin: 0;
+ padding: 0;
+}
+
+.main .ctzgen .bg .owl-carousel .owl-stage-outer .owl-stage {
+ width: 1920px;
+ height: 1080px;
+ margin: 0;
+ padding: 0;
+}
+
+.main .ctzgen .bg .owl-carousel .owl-stage-outer .owl-stage .owl-item {
+ width: 1920px;
+ height: 1080px;
+ margin: 0;
+ padding: 0;
+}
+
+.main .ctzgen .bg .owl-carousel .owl-stage-outer .owl-stage .owl-item>div {
+ width: 1920px;
+ height: 1080px;
+ background-image: var(--bg_noplay);
+}
+
+.main .ctzgen .bg .owl-carousel .owl-stage-outer .owl-stage .owl-item.movieplay>div {
+ width: 1920px;
+ height: 1080px;
+ background-image: url(tv:);
+}
+
+.main .ctzgen .bg .owl-carousel .owl-stage-outer .owl-stage .owl-item.movieplay .item .ctz_desc_frame {
+ opacity: 1;
+ animation-delay: 6s;
+ animation-name: fadeOutCtzDescFrame;
+ animation-iteration-count: 1;
+ animation-timing-function: ease-in;
+ animation-fill-mode: forwards;
+ animation-duration: 2s;
+}
+
+@keyframes fadeOutCtzDescFrame {
+ 0% {
+ opacity: 1;
+ }
+ 100% {
+ opacity: 0;
+ }
+}
+
+
+/* OWL Contents Menu Selector Container */
+
+.main .ctzgen .slider .owl-carousel .owl-item.active.focus div [id*="ctzgen_item_icon"] {
+ background-image: var(--icon_focus);
+}
+
+.main .ctzgen .slider .owl-carousel .owl-item.active[class*="unfocus"] div [id*="ctzgen_item_icon"] {
+ background-image: var(--icon_unfocus);
+}
+
+.main .ctzgen .slider .owl-carousel .owl-item.active.focus div [id*="ctzgen_item_title"] {
+ transform: scale(1.2);
+}
+
+.main .ctzgen .bg .owl-carousel .owl-item .ctz_desc_frame {
+ position: absolute;
+ top: 150px;
+ left: 40px;
+ width: 400px;
+ height: 800px;
+ color: rgb(255, 255, 255);
+}
+
+.main .ctzgen .bg .owl-carousel .owl-item .ctz_desc_frame #ctz_title {
+ position: absolute;
+ font-size: 60px;
+ width: 1800px;
+ padding: 10px;
+ overflow: hidden;
+}
+
+.main .ctzgen .bg .owl-carousel .owl-item .ctz_desc_frame #ctz_thumbnail {
+ margin: 120px 10px 40px 10px;
+ height: 220px;
+ filter: drop-shadow(0 0 10px rgba(0, 0, 0, 1));
+ /* border: 4px solid rgb(255, 255, 255); */
+}
+
+.main .ctzgen .bg .owl-carousel .owl-item .ctz_desc_frame #ctz_thumbnail img {
+ width: auto;
+ height: 212px;
+ overflow: hidden;
+ border: 2px solid rgb(40, 40, 40);
+}
+
+.main .ctzgen .bg .owl-carousel .owl-item .ctz_desc_frame #ctz_description {
+ position: absolute;
+ font-size: 26px;
+ width: 700px;
+ line-height: 26px;
+ margin: 0 10px 0 10px;
+}
+
+.main .ctzgen .bg .owl-carousel .owl-item .ctz_mv_ctrl {
+ position: absolute;
+ top: 870px;
+ left: 1700px;
+ height: 54px;
+ line-height: 54px;
+ color: rgb(235, 235, 235);
+ font-size: 38px;
+ filter: drop-shadow(0 0 5px rgb(0, 0, 0));
+ white-space: nowrap;
+}
+
+.main .ctzgen .bg .owl-carousel .owl-item.movieplay .item .ctz_mv_ctrl {
+ animation-delay: 4s;
+ animation-name: moveCtzMvCtrl;
+ animation-iteration-count: 1;
+ animation-timing-function: ease-in;
+ animation-fill-mode: forwards;
+ animation-duration: 1s;
+}
+
+@keyframes moveCtzMvCtrl {
+ from {
+ left: 1700px;
+ }
+ to {
+ left: 2220px
+ }
+}
+
+.main .ctzgen .bg .owl-carousel .owl-item .ctz_mv_ctrl::before {
+ position: absolute;
+ content: '';
+ width: 128px;
+ height: 54px;
+ margin-left: -140px;
+ background-image: url("./images/icons/icon_btn_media_play.png");
+ background-repeat: no-repeat;
+ background-position: right center;
+ background-size: contain;
+}
+
+.main .ctzgen .bg .owl-carousel .owl-item.movieplay .ctz_mv_ctrl::before {
+ animation-name: iconCtzMvCtrlBtn;
+ animation-iteration-count: 1;
+ animation-timing-function: ease-in;
+ animation-fill-mode: forwards;
+ animation-duration: 1s;
+}
+
+@keyframes iconCtzMvCtrlBtn {
+ 0% {
+ transform: rotateX(0deg);
+ }
+ 50% {
+ transform: rotateX(90deg);
+ background-image: url("./images/icons/icon_btn_media_stop.png");
+ }
+ 100% {
+ transform: rotateX(0deg);
+ background-image: url("./images/icons/icon_btn_media_stop.png");
+ }
+}
+
+.main .ctzgen .bg .owl-carousel .owl-item .ctz_mv_ctrl::after {
+ content: var(--playmsg);
+}
+
+.main .ctzgen .bg .owl-carousel .owl-item.movieplay .ctz_mv_ctrl::after {
+ animation-delay: 1s;
+ animation-name: msgCtzMvCtrlBtn;
+ animation-iteration-count: 1;
+ animation-timing-function: ease-in;
+ animation-fill-mode: forwards;
+ animation-duration: 2s;
+}
+
+@keyframes msgCtzMvCtrlBtn {
+ 0% {
+ opacity: 1;
+ }
+ 25% {
+ opacity: 0;
+ content: var(--stopmsg);
+ }
+ 50% {
+ opacity: 1;
+ content: var(--stopmsg);
+ }
+ 100% {
+ opacity: 1;
+ content: var(--stopmsg);
+ }
+}
+
+.image-slider {
+ position: absolute;
+ top: 0px;
+ left: 0px;
+ width: 480px;
+ height: 272px;
+}
+
+.main #imageGallery {
+ position: absolute;
+ top: 0px;
+ left: 0%;
+ width: 480px;
+ height: 272px;
+ padding: 0px;
+ overflow: hidden;
+}
\ No newline at end of file
diff --git a/procentric/application/hoteltv.app.full.guide.css b/procentric/application/hoteltv.app.full.guide.css
new file mode 100755
index 0000000..88c22ce
--- /dev/null
+++ b/procentric/application/hoteltv.app.full.guide.css
@@ -0,0 +1,26 @@
+/* Brocure */
+
+.guide {
+ position: absolute;
+ top: 0px;
+ left: 0px;
+ width: 1920px;
+ height: 1080px;
+ margin: 0;
+ padding: 0;
+ z-index: 2;
+ display: block;
+}
+
+.guide>.tips {
+ position: absolute;
+ top: 1034px;
+ left: 0px;
+ width: 1920px;
+ height: 46px;
+ font-size: 32px;
+ text-align: center;
+ line-height: 45px;
+ background-color: rgba(0, 0, 0, 0.55);
+ color: rgb(255, 255, 255);
+}
\ No newline at end of file
diff --git a/procentric/application/hoteltv.app.full.mm.css b/procentric/application/hoteltv.app.full.mm.css
new file mode 100755
index 0000000..a2db651
--- /dev/null
+++ b/procentric/application/hoteltv.app.full.mm.css
@@ -0,0 +1,124 @@
+/* STEP[#002]: Define MAIN-MENU BG FRAMES */
+
+.main .mm {
+ top: 0px;
+ left: 0px;
+ width: 100%;
+ height: 100%;
+}
+
+.main .mm .bg {
+ position: absolute;
+ top: 0px;
+ left: 0px;
+ width: 100%;
+ height: 100%;
+ padding: 0px;
+ overflow: hidden;
+ display: none;
+}
+
+.main .mm .bg div {
+ width: 100%;
+ height: 100%;
+ margin: 0;
+ padding: 0;
+}
+
+.main .mm .bg div .item {
+ width: 100%;
+ height: 100%;
+ margin: 0;
+ padding: 0;
+}
+
+.main .mm .bg .owl-carousel .owl-stage-outer .owl-stage .owl-item {
+ width: 100%;
+}
+
+
+/* STEP[#003]: Define MAIN-MENU SELECTOR FRAMES */
+
+.main .mm .slider {
+ position: absolute;
+ /* top: 734px; */
+ top: 884px;
+ left: 0px;
+ width: 1920px;
+ /* height: 300px; */
+ padding: 0px;
+ overflow: hidden;
+ display: none;
+}
+
+.main .mm .slider .owl-carousel.owl-theme {
+ /* height: 266px;
+ max-height: 266px; */
+ height: 100%;
+ padding-left: 0;
+ margin: 50px 0 0 0;
+}
+
+.main .mm .slider .owl-carousel.owl-theme .owl-carousel-outer {
+ /* height: 266px;
+ max-height: 266px; */
+ height: 100%;
+ padding-left: 0;
+ margin: 0;
+}
+
+div#mm_item_title {
+ position: absolute;
+ /* top: 190px; */
+ top: 22px;
+ width: 100%;
+ height: 100%;
+ margin: 0;
+ padding: 0;
+ color: rgb(235, 235, 235);
+ font-size: 2.2vw;
+ white-space: nowrap;
+ text-align: center;
+}
+
+div#mm_item_icon {
+ height: 100%;
+ margin: 0;
+ padding: 0;
+ display: block
+}
+
+
+/* OWL Main Menu Selector Container */
+
+.main .mm .slider .owl-dots {
+ position: absolute;
+ top: -45px;
+ width: 100%;
+ align-content: center;
+}
+
+
+/* .main .mm .slider .owl-carousel .owl-item.active.focus div {
+ transform: scale(1.14);
+} */
+
+.main .mm .slider .owl-carousel .owl-item.active.focus:after {
+ width: 336px;
+}
+
+.main .mm .slider .owl-carousel .owl-item.active[class*="unfocus"]:after {
+ width: 264px;
+}
+
+.main .mm .slider .owl-carousel .owl-item.active.focus div [id*="mm_item_icon"] {
+ background-image: var(--icon_focus);
+}
+
+.main .mm .slider .owl-carousel .owl-item.active[class*="unfocus"] div [id*="mm_item_icon"] {
+ background-image: var(--icon_unfocus);
+}
+
+.main .mm .slider .owl-carousel .owl-item.active.focus div [id*="mm_item_title"] {
+ transform: scale(1.1);
+}
\ No newline at end of file
diff --git a/procentric/application/hoteltv.app.full.mm.flight.css b/procentric/application/hoteltv.app.full.mm.flight.css
new file mode 100755
index 0000000..61b4750
--- /dev/null
+++ b/procentric/application/hoteltv.app.full.mm.flight.css
@@ -0,0 +1,150 @@
+/* =============================
+ Main Menu Flight Format
+*/
+
+.main .mm .flight {
+ position: absolute;
+ top: 120px;
+ left: 0px;
+ width: 100%;
+ height: 620px;
+ max-height: 620px;
+ padding-left: 0;
+ margin: 0;
+ background-color: rgba(0, 0, 0, .5);
+ filter: drop-shadow(4px 4px 10px rgba(255, 255, 255, 0.8));
+ overflow: hidden;
+ z-index: 1;
+ display: none;
+}
+
+.main .mm .flight #title {
+ font-size: 40px;
+ color: rgb(235, 235, 235);
+}
+
+.main .mm .flight table {
+ position: absolute;
+ width: 940px;
+ height: 540px;
+ margin-left: 10px;
+ margin-right: 10px;
+ color: rgb(235, 235, 235);
+ text-align: center;
+ white-space: normal;
+ word-break: break-word;
+ border-collapse: collapse;
+ display: block;
+ overflow: auto;
+}
+
+
+/* .main .mm .flight table::-webkit-scrollbar {
+ display: none;
+} */
+
+.main .mm .flight table tbody#record {
+ position: absolute;
+ width: 100%;
+ height: 460px;
+ top: 52px;
+ overflow-y: scroll;
+}
+
+.main .mm .flight .tbl_header tr {
+ height: 50px;
+ max-height: 50px;
+}
+
+.main .mm .flight table #airline {
+ width: 118px;
+ max-width: 120px;
+}
+
+.main .mm .flight table #flight {
+ width: 70px;
+ max-width: 70px;
+}
+
+.main .mm .flight table #scheduled {
+ width: 128px;
+ max-width: 130px;
+}
+
+.main .mm .flight table #origin {
+ width: 88px;
+ max-width: 90px;
+}
+
+.main .mm .flight table #destination {
+ width: 122px;
+ max-width: 124px;
+}
+
+.main .mm .flight table #type {
+ width: 148px;
+ max-width: 150px;
+}
+
+.main .mm .flight table #gate {
+ width: 58px;
+ max-width: 60px;
+}
+
+.main .mm .flight table td#status {
+ width: 168px;
+ max-width: 169px;
+}
+
+.main .mm .flight table th#airline {
+ border-top-left-radius: 10px;
+}
+
+.main .mm .flight table th#status {
+ width: 168px;
+ max-width: 169px;
+ border-top-right-radius: 10px;
+}
+
+.main .mm .flight table th {
+ font-size: 20px;
+ color: rgb(235, 235, 235);
+ background: rgba(0, 0, 0, 0.4);
+}
+
+.main .mm .flight table td {
+ font-size: 20px;
+ color: rgb(235, 235, 235);
+ background: rgba(0, 0, 0, 0.2);
+}
+
+.main .mm .flight ::-webkit-scrollbar {
+ display: block;
+ width: 20px;
+ /* 세로축 스크롤바 길이 */
+ height: 20px;
+ /* 가로축 스크롤바 길이 */
+}
+
+.main .mm .flight ::-webkit-scrollbar-track {
+ background-color: lightblue;
+}
+
+.main .mm .flight ::-webkit-scrollbar-track-piece {
+ background-color: gray;
+}
+
+.main .mm .flight ::-webkit-scrollbar-thumb {
+ border-radius: 8px;
+ background-color: rgba(0, 0, 0, 0.7);
+}
+
+.main .mm .flight ::-webkit-scrollbar-button:start {
+ background-color: orange;
+ /* Top, Left 방향의 이동버튼 */
+}
+
+.main .mm .flight ::-webkit-scrollbar-button:end {
+ background-color: orange;
+ /* Bottom, Right 방향의 이동버튼 */
+}
\ No newline at end of file
diff --git a/procentric/application/hoteltv.app.full.mm.weather.css b/procentric/application/hoteltv.app.full.mm.weather.css
new file mode 100755
index 0000000..c446008
--- /dev/null
+++ b/procentric/application/hoteltv.app.full.mm.weather.css
@@ -0,0 +1,186 @@
+/* =============================
+ Main Menu Weather Format
+*/
+
+.main .mm .weather {
+ position: absolute;
+ top: 200px;
+ left: 0px;
+ width: 100%;
+ height: 400px;
+ max-height: 400px;
+ padding-left: 0;
+ margin: 0;
+ background-color: rgba(235, 235, 235, .5);
+ filter: drop-shadow(4px 4px 10px rgba(0, 0, 0, 0.8));
+ z-index: 1;
+ display: none;
+}
+
+.main .mm .weather .location {
+ position: absolute;
+ top: 40px;
+ left: 100px;
+ font-size: 50px;
+ justify-content: center;
+ text-align: center;
+ color: rgb(235, 235, 235);
+ z-index: 1;
+ display: block;
+}
+
+.main .mm .weather .today {
+ position: absolute;
+ top: 0px;
+ left: 100px;
+ width: 320px;
+ height: 100%;
+}
+
+.main .mm .weather .today #temp_cur {
+ position: relative;
+ top: 110px;
+ font-size: 160px;
+ text-align: center;
+ color: rgb(21, 126, 251);
+}
+
+.main .mm .weather .today #temp_minmax {
+ position: relative;
+ top: 120px;
+ font-size: 50px;
+ text-align: right;
+ color: rgb(235, 235, 235);
+ display: block;
+}
+
+.main .mm .weather .today .detail {
+ position: absolute;
+ top: 40px;
+ left: 400px;
+ width: 400px;
+ height: 360px;
+ color: rgb(235, 235, 235);
+ overflow: hidden;
+ display: block;
+}
+
+.main .mm .weather .today .detail #discription {
+ height: 50px;
+ font-size: 40px;
+ text-align: center;
+ display: block;
+}
+
+.main .mm .weather .today .detail #img_status {
+ height: 160px;
+ background-repeat: no-repeat;
+ background-size: contain;
+ background-position: center center;
+ display: block;
+}
+
+.main .mm .weather .today .detail #humidity {
+ width: 100%;
+ padding: 20px;
+ height: 40px;
+ text-align: center;
+ display: block;
+}
+
+.main .mm .weather .today .detail #wind {
+ width: 100%;
+ height: 40px;
+ text-align: center;
+ display: block;
+ margin-top: 24px;
+}
+
+.main .mm .weather .today .detail #icon {
+ filter: drop-shadow(3px 3px 5px rgba(0, 0, 0, 0.8));
+}
+
+.main .mm .weather .forcast .daily {
+ position: absolute;
+ top: 10px;
+ left: 1000px;
+ width: 910px;
+ height: 180px;
+ background-color: rgba(0, 0, 0, 0.2);
+ border-top-left-radius: 10px;
+ border-top-right-radius: 10px;
+ padding: 5px 0 0 10px;
+ color: rgb(235, 235, 235);
+}
+
+.main .mm .weather .forcast .daily ul {
+ width: 95%;
+ height: 100px;
+ list-style: none;
+}
+
+.main .mm .weather .forcast .daily li {
+ width: 150px;
+ height: 90px;
+ font-size: 24px;
+ background-repeat: no-repeat;
+ background-size: contain;
+ background-position: right center;
+ filter: drop-shadow(3px 3px 5px rgba(0, 0, 0, 0.8));
+ float: left;
+ display: inline;
+ margin: 0 10px 0 10px;
+ list-style: none;
+}
+
+.main .mm .weather .forcast div#time {
+ height: 90%;
+ text-align: left;
+ color: rgb(170, 170, 170);
+}
+
+.main .mm .weather .forcast div#temp {
+ margin-top: 8px;
+ height: 30%;
+ text-align: left;
+ color: rgb(170, 170, 170);
+}
+
+.main .mm .weather .forcast .weekly {
+ position: absolute;
+ top: 200px;
+ left: 1000px;
+ width: 910px;
+ height: 190px;
+ background-color: rgba(0, 0, 0, 0.2);
+ border-bottom-left-radius: 10px;
+ border-bottom-right-radius: 10px;
+ padding: 0 0 0 10px;
+ color: rgb(235, 235, 235);
+}
+
+.main .mm .weather .forcast .weekly ul {
+ width: 95%;
+ height: 100px;
+ list-style: none;
+}
+
+.main .mm .weather .forcast .weekly li {
+ width: 150px;
+ height: 90px;
+ font-size: 24px;
+ background-repeat: no-repeat;
+ background-size: contain;
+ background-position: right center;
+ filter: drop-shadow(3px 3px 5px rgba(0, 0, 0, 0.8));
+ float: left;
+ display: inline;
+ margin: 0 10px 0 10px;
+ list-style: none;
+}
+
+.main .mm .weather .forcast div#date {
+ height: 90%;
+ text-align: left;
+ color: rgb(170, 170, 170);
+}
\ No newline at end of file
diff --git a/procentric/application/hoteltv.app.full.mypage.css b/procentric/application/hoteltv.app.full.mypage.css
new file mode 100755
index 0000000..ecba110
--- /dev/null
+++ b/procentric/application/hoteltv.app.full.mypage.css
@@ -0,0 +1,405 @@
+.main .mypage {
+ position: absolute;
+ top: 1080px;
+ left: 0px;
+ width: 1920px;
+ height: 1080px;
+ background-color: black;
+ display: none;
+}
+
+.main .mypage .bg {
+ position: absolute;
+ top: 0px;
+ left: 0%;
+ width: 100%;
+ height: 100%;
+ padding: 0px;
+ overflow: hidden;
+ display: block;
+}
+
+.main .mypage .bg div#lst_mypagebg {
+ width: 100%;
+ height: 100%;
+ margin: 0;
+ padding: 0;
+}
+
+.main .mypage .bg .owl-carousel .owl-stage-outer {
+ width: 100%;
+ height: 100%;
+ margin: 0;
+ padding: 0;
+}
+
+.main .mypage .bg .owl-carousel .owl-stage-outer .owl-stage {
+ width: 100%;
+ height: 100%;
+ margin: 0;
+ padding: 0;
+}
+
+.main .mypage .bg .owl-carousel .owl-stage-outer .owl-stage .owl-item {
+ width: 100%;
+ height: 100%;
+ margin: 0;
+ padding: 0;
+}
+
+.main .mypage .bg div .item {
+ width: 100%;
+ height: 100%;
+ margin: 0;
+ padding: 0;
+}
+
+
+/* STEP[#003]: Define SUB-MENU SELECTOR FRAMES */
+
+.main .mypage .slider {
+ position: absolute;
+ top: 864px;
+ left: 0px;
+ width: 1920px;
+ height: 170px;
+ padding-top: 50px;
+ overflow: hidden;
+ display: none;
+}
+
+.main .mypage .slider div {
+ height: 120px;
+ max-height: 120px;
+ padding-left: 0;
+ margin: 0;
+}
+
+div#mp_item_title {
+ position: absolute;
+ top: 40px;
+ width: 100%;
+ height: 100%;
+ margin: 0;
+ padding: 0;
+ color: rgb(235, 235, 235);
+ font-size: 2.2vw;
+ white-space: nowrap;
+ text-align: center;
+}
+
+div#mp_item_icon {
+ margin: 0;
+ padding: 0;
+ display: block
+}
+
+div#lst_mypagebg div #mp_accomo_title {
+ position: absolute;
+ top: 165px;
+ left: 224px;
+ width: 1536px;
+ height: 42px;
+ line-height: 42px;
+ color: rgb(235, 235, 235);
+ font-size: 46px;
+}
+
+div#lst_mypagebg div #mp_accomo_title::before {
+ position: absolute;
+ content: '';
+ width: 48px;
+ height: 40px;
+ margin-left: -62px;
+ background-image: url("./images/icons/icon_mypage_title.png");
+ background-repeat: no-repeat;
+ background-position: right center;
+ background-size: contain;
+ filter: drop-shadow(0 0 5px rgba(0, 0, 0, 1));
+}
+
+div#lst_mypagebg div #mp_accomo_infowin {
+ position: absolute;
+ top: 230px;
+ left: 160px;
+ width: 1600px;
+ height: 600px;
+ padding: 30px 10px 10px 10px;
+ color: rgb(235, 235, 235);
+ border: 1px solid rgb(28, 28, 28);
+ background-color: rgba(0, 0, 0, 0.5);
+ filter: drop-shadow(0 0 10px rgba(0, 0, 0, 0.9));
+}
+
+div#lst_mypagebg div #mp_accomo_infowin .accmoinf_item {
+ font-size: 32px;
+}
+
+div#lst_mypagebg div #mp_accomo_infowin .accmoinf_item #header {
+ width: 20%;
+ height: 50px;
+ text-align: right;
+ display: inline-block;
+}
+
+div#lst_mypagebg div #mp_accomo_infowin .accmoinf_item #value {
+ width: 80%;
+ margin-left: 50px;
+}
+
+div#lst_mypagebg div #mp_hotel_infowin {
+ position: absolute;
+ top: 664px;
+ left: 190px;
+ width: 1540px;
+ height: 132px;
+ background-color: rgba(84, 84, 84, 0.9);
+ padding: 10px 11px 10px 11px;
+ filter: drop-shadow(0 4px 5px rgba(0, 0, 0, 1));
+}
+
+div#lst_mypagebg div #mp_hotel_infowin .hotelinfo_item {
+ width: 506px;
+ height: 100%;
+ display: inline-block;
+ padding: 5px;
+ font-size: 20px;
+ color: rgb(235, 235, 235);
+ text-shadow: 0 0 3px rgba(0, 0, 0, 1);
+}
+
+div#lst_mypagebg div #mp_hotel_infowin .hotelinfo_item #title {
+ display: block;
+ font-size: 26px;
+}
+
+div#lst_mypagebg div #mp_hotel_infowin .hotelinfo_item #address {
+ position: absolute;
+ width: 470px;
+ top: 60px;
+ margin-left: 26px
+}
+
+div#lst_mypagebg div #mp_hotel_infowin .hotelinfo_item #address::before {
+ position: absolute;
+ content: '';
+ width: 30px;
+ height: 26px;
+ margin-left: -32px;
+ background-image: url("./images/icons/icon_place_48x48.png");
+ background-repeat: no-repeat;
+ background-position: right center;
+ background-size: contain;
+ filter: drop-shadow(0 3px 5px rgba(0, 0, 0, 1));
+}
+
+div#lst_mypagebg div #mp_hotel_infowin .hotelinfo_item #email {
+ position: absolute;
+ width: 470px;
+ top: 60px;
+ margin-left: 32px
+}
+
+div#lst_mypagebg div #mp_hotel_infowin .hotelinfo_item #email::before {
+ position: absolute;
+ content: '';
+ width: 30px;
+ height: 26px;
+ margin-left: -36px;
+ background-image: url("./images/icons/icon_cotact_email_48x48.png");
+ background-repeat: no-repeat;
+ background-position: right center;
+ background-size: contain;
+ filter: drop-shadow(0 0 5px rgba(0, 0, 0, 1));
+}
+
+div#lst_mypagebg div #mp_hotel_infowin .hotelinfo_item #phone {
+ position: absolute;
+ width: 470px;
+ top: 90px;
+ margin-left: 32px
+}
+
+div#lst_mypagebg div #mp_hotel_infowin .hotelinfo_item #phone::before {
+ position: absolute;
+ content: '';
+ width: 30px;
+ height: 26px;
+ margin-left: -36px;
+ background-image: url("./images/icons/icon_contact_phone_48x48.png");
+ background-repeat: no-repeat;
+ background-position: right center;
+ background-size: contain;
+ filter: drop-shadow(0 0 5px rgba(0, 0, 0, 1));
+}
+
+div#lst_mypagebg div #mp_message_title {
+ position: absolute;
+ top: 165px;
+ left: 224px;
+ width: 1536px;
+ height: 42px;
+ line-height: 42px;
+ color: rgb(235, 235, 235);
+ font-size: 46px;
+}
+
+div#lst_mypagebg div #mp_message_title::before {
+ position: absolute;
+ content: '';
+ width: 48px;
+ height: 40px;
+ margin-left: -62px;
+ background-image: url("./images/icons/icon_cotact_email_96x96.png");
+ background-repeat: no-repeat;
+ background-position: right center;
+ background-size: contain;
+ filter: drop-shadow(0 0 5px rgba(0, 0, 0, 1));
+}
+
+div#lst_mypagebg div #mp_message_table {
+ position: absolute;
+ top: 230px;
+ left: 160px;
+ width: 1600px;
+ height: 600px;
+ padding: 10px 10px 10px 32px;
+ color: rgb(235, 235, 235);
+ border: 1px solid rgb(28, 28, 28);
+ background-color: rgba(0, 0, 0, 0.5);
+ filter: drop-shadow(0 0 10px rgba(0, 0, 0, 0.9));
+}
+
+div#lst_mypagebg div #mp_message_table>#mp_msg_tblhdr {
+ position: absolute;
+ width: 1580px;
+ font-size: 36px;
+ line-height: 74px;
+ display: block;
+ border-collapse: collapse;
+}
+
+div#lst_mypagebg div #mp_message_table>#mp_msg_tblhdr tr {
+ text-align: center;
+ box-shadow: 0 2px 4px rgba(0, 0, 0, 0.65);
+}
+
+div#lst_mypagebg div #mp_message_table>#mp_msg_tblhdr tr th {
+ border-bottom: 5px solid rgb(94, 94, 94, 1);
+}
+
+div#lst_mypagebg div #mp_message_table>#mp_msg_tblhdr tr>#num {
+ width: 160px;
+}
+
+div#lst_mypagebg div #mp_message_table>#mp_msg_tblhdr tr>#title {
+ width: 780px;
+}
+
+div#lst_mypagebg div #mp_message_table>#mp_msg_tblhdr tr>#from {
+ width: 354px;
+}
+
+div#lst_mypagebg div #mp_message_table>#mp_msg_tblhdr tr>#date {
+ width: 236px;
+}
+
+div#lst_mypagebg div #mp_message_table>#mp_msg_tblrec {
+ position: absolute;
+ top: 90px;
+ width: 1580px;
+ height: 478px;
+ font-size: 32px;
+ overflow: auto;
+ display: block;
+ border-collapse: separate;
+ border-spacing: 0 16px;
+ text-shadow: 0 0 5px rgba(0, 0, 0, 1), 0 0 5px rgba(0, 0, 0, 1);
+}
+
+div#lst_mypagebg div #mp_message_table>#mp_msg_tblrec tbody {
+ position: absolute;
+ width: 100%;
+ height: 100%;
+ overflow-y: scroll;
+}
+
+div#lst_mypagebg div #mp_message_table>#mp_msg_tblrec tr {
+ line-height: 52px;
+ text-align: center;
+}
+
+div#lst_mypagebg div #mp_message_table>#mp_msg_tblrec tr.focus {
+ background-color: rgba(127, 127, 127, 0.9);
+ box-shadow: 0 2px 4px rgba(0, 0, 0, 0.65);
+}
+
+div#lst_mypagebg div #mp_message_table>#mp_msg_tblrec tr td {}
+
+div#lst_mypagebg div #mp_message_table>#mp_msg_tblrec tr>#num {
+ width: 160px;
+ padding-left: 90px;
+ text-align: left;
+}
+
+div#lst_mypagebg div #mp_message_table>#mp_msg_tblrec tr>#num::before {
+ position: absolute;
+ content: '';
+ background-image: url(./images/icons/icon_unread_message_48x48.png);
+ margin-top: 6px;
+ width: 42px;
+ height: 38px;
+ margin-left: -64px;
+ background-repeat: no-repeat;
+ background-position: center;
+ background-size: contain;
+ filter: drop-shadow(0 0 4px rgb(0, 0, 0));
+}
+
+div#lst_mypagebg div #mp_message_table>#mp_msg_tblrec tr>#num.read::before {
+ position: absolute;
+ content: '';
+ background-image: url(./images/icons/icon_read_message_48x48.png);
+ margin-top: 6px;
+ width: 42px;
+ height: 38px;
+ margin-left: -64px;
+ background-repeat: no-repeat;
+ background-position: center;
+ background-size: contain;
+ filter: drop-shadow(0 0 4px rgb(0, 0, 0));
+}
+
+div#lst_mypagebg div #mp_message_table>#mp_msg_tblrec tr>#title {
+ width: 780px;
+}
+
+div#lst_mypagebg div #mp_message_table>#mp_msg_tblrec tr>#from {
+ width: 354px;
+}
+
+div#lst_mypagebg div #mp_message_table>#mp_msg_tblrec tr>#date {
+ width: 236px;
+}
+
+
+/* OWL Sub Menu Selector Container */
+
+.main .mypage .slider .owl-carousel .owl-item.active.focus div [id*="mp_item_icon"] {
+ background-image: var(--icon_focus);
+}
+
+.main .mypage .slider .owl-carousel .owl-item.active[class*="unfocus"] div [id*="mp_item_icon"] {
+ background-image: var(--icon_unfocus);
+}
+
+.main .mypage .slider .owl-carousel .owl-item.active.focus div [id*="mp_item_title"] {
+ transform: scale(1.2);
+}
+
+.main .mypage .slider .owl-dots {
+ position: absolute;
+ top: -50px;
+ width: 100%;
+ align-content: center;
+}
\ No newline at end of file
diff --git a/procentric/application/hoteltv.app.full.news.css b/procentric/application/hoteltv.app.full.news.css
new file mode 100755
index 0000000..9dba816
--- /dev/null
+++ b/procentric/application/hoteltv.app.full.news.css
@@ -0,0 +1,42 @@
+/* 뉴스 */
+
+.news {
+ position: absolute;
+ top: 1044px;
+ left: 0;
+ width: 100%;
+ height: 36px;
+ background-color: rgba(19, 21, 23, 0.6);
+ filter: drop-shadow(0 -10px 5px rgba(0, 0, 0, 0.5));
+ display: none;
+ z-index: 1;
+}
+
+.news>.title {
+ position: absolute;
+ width: 160px;
+ color: rgb(235, 235, 235);
+ font-size: 32px;
+ line-height: 40px;
+ text-align: center;
+ border: solid rgba(0, 0, 0, 0.5);
+ margin: 0 20px 0 20px;
+ background-color: rgba(128, 128, 128, 0.3);
+}
+
+.news>.newsctz {
+ padding: 0;
+ margin: 8px 0 0 200px;
+ color: rgb(165, 175, 185);
+}
+
+.news>.newsctz #hoteltv-news-ticker li {
+ font-size: 28px;
+}
+
+.news>.newsctz #hoteltv-news-ticker li img {
+ height: 40px;
+ vertical-align: middle;
+ padding: 3px 10px 10px 0;
+ object-fit: cover;
+}
\ No newline at end of file
diff --git a/procentric/application/hoteltv.app.full.popup.css b/procentric/application/hoteltv.app.full.popup.css
new file mode 100755
index 0000000..9188fd0
--- /dev/null
+++ b/procentric/application/hoteltv.app.full.popup.css
@@ -0,0 +1,1049 @@
+/* Font */
+
+@font-face {
+ font-family: Parisienne;
+ src: url(./fonts/Parisienne/Parisienne-Regular.ttf);
+}
+
+@font-face {
+ font-family: Nanum Pen Script;
+ src: url(./fonts/Nanum_Pen_Script/NanumPenScript-Regular.ttf);
+}
+
+@font-face {
+ font-family: Ma Shan Zheng;
+ src: url(./fonts/Ma_Shan_Zheng/MaShanZheng-Regular.ttf);
+}
+
+
+/* POPUP */
+
+.popup {
+ position: absolute;
+ top: 0px;
+ left: 0px;
+ width: 1920px;
+ height: 1080px;
+ display: block;
+ z-index: 1;
+}
+
+
+/* Hotkey(main menu) red */
+
+.popup .hotkey_mm_red {
+ position: absolute;
+ width: 100%;
+ height: 100%;
+ padding: 0px;
+ overflow: hidden;
+ display: none;
+}
+
+.popup .hotkey_mm_red div#lst_hotkey_mm_red {
+ position: absolute;
+ /*
+ width: 1464px;
+ height: 1007px;
+ margin: 36px 226px 36px 226px;
+ */
+ width: 100%;
+ height: 100%;
+ padding: 0;
+ border-style: solid;
+ border-color: rgb(160, 160, 160);
+ filter: drop-shadow(0 0 15px rgba(255, 255, 255, 1));
+}
+
+.popup .hotkey_mm_red .owl-carousel .owl-stage-outer {
+ width: 100%;
+ height: 100%;
+ margin: 0;
+ padding: 0;
+}
+
+.popup .hotkey_mm_red .owl-carousel .owl-stage-outer .owl-stage {
+ width: 100%;
+ height: 100%;
+ margin: 0;
+ padding: 0;
+}
+
+.popup .hotkey_mm_red .owl-carousel .owl-stage-outer .owl-stage .owl-item {
+ width: 100%;
+ height: 100%;
+ margin: 0;
+ padding: 0;
+}
+
+.popup .hotkey_mm_red div .item {
+ width: 100%;
+ height: 100%;
+ margin: 0;
+ padding: 0;
+}
+
+.popup .hotkey_mm_red .owl-nav {
+ position: absolute;
+ top: 420px;
+ width: 100%;
+ height: 120px;
+}
+
+.popup .hotkey_mm_red .owl-nav .owl-prev {
+ position: absolute;
+ height: 100%;
+ /* top: -40px; */
+ left: 0px;
+ width: 60px;
+ font-size: 100px;
+ /* border-radius: 10px; */
+ background: rgba(60, 60, 60, 1);
+ line-height: 100px;
+ color: #FFFFFF;
+ text-align: center;
+ display: inline-block;
+ box-shadow: -2px 0px 8px #999;
+}
+
+.popup .hotkey_mm_red .owl-nav .owl-next {
+ position: absolute;
+ height: 100%;
+ /* top: -40px; */
+ left: 1845px;
+ width: 60px;
+ font-size: 100px;
+ /* border-radius: 10px; */
+ background: rgba(60, 60, 60, 1);
+ line-height: 100px;
+ color: #FFFFFF;
+ text-align: center;
+ display: inline-block;
+ box-shadow: 2px 0px 8px #999;
+}
+
+.popup .hotkey_mm_red .owl-dots {
+ position: absolute;
+ top: 966px;
+ width: 100%;
+ align-content: center;
+}
+
+.popup .hotkey_mm_red .owl-dots .owl-dot span {
+ width: 14px;
+}
+
+.popup .hotkey_mm_red .owl-nav .owl-prev {
+ /* width: 100%; */
+}
+
+.popup .hotkey_mm_red .owl-nav .owl-next {
+ /* width: 100%; */
+}
+
+
+/* Hotkey(main menu) green */
+
+.popup .hotkey_mm_green {
+ position: absolute;
+ width: 100%;
+ height: 100%;
+ padding: 0px;
+ overflow: hidden;
+ display: none;
+}
+
+.popup .hotkey_mm_green div#lst_hotkey_mm_green {
+ position: absolute;
+ /*
+ width: 1464px;
+ height: 1007px;
+ margin: 36px 226px 36px 226px;
+ */
+ width: 100%;
+ height: 100%;
+ padding: 0;
+ border-style: solid;
+ border-color: rgb(160, 160, 160);
+ filter: drop-shadow(0 0 15px rgba(255, 255, 255, 1));
+}
+
+.popup .hotkey_mm_green .owl-carousel .owl-stage-outer {
+ width: 100%;
+ height: 100%;
+ margin: 0;
+ padding: 0;
+}
+
+.popup .hotkey_mm_green .owl-carousel .owl-stage-outer .owl-stage {
+ width: 100%;
+ height: 100%;
+ margin: 0;
+ padding: 0;
+}
+
+.popup .hotkey_mm_green .owl-carousel .owl-stage-outer .owl-stage .owl-item {
+ width: 100%;
+ height: 100%;
+ margin: 0;
+ padding: 0;
+}
+
+.popup .hotkey_mm_green div .item {
+ width: 100%;
+ height: 100%;
+ margin: 0;
+ padding: 0;
+}
+
+.popup .hotkey_mm_green .owl-dots {
+ position: absolute;
+ top: 966px;
+ width: 100%;
+ align-content: center;
+}
+
+.popup .hotkey_mm_green .owl-dots .owl-dot span {
+ width: 14px;
+}
+
+
+/* Amenity Style */
+
+.popup .amenity {
+ position: absolute;
+ top: 96px;
+ left: -560px;
+ width: 496px;
+ height: 700px;
+ overflow: hidden;
+ display: none;
+ background-color: rgba(67, 67, 67, 1);
+ border-style: solid;
+ border-color: rgb(96, 96, 96);
+ filter: drop-shadow(0 0 10px rgba(255, 255, 255, 1));
+}
+
+.popup .amenity .title {
+ width: 100%;
+ height: 64px;
+ line-height: 40px;
+ overflow: hidden;
+ color: rgb(247, 236, 234);
+ font-size: 40px;
+ text-align: left;
+ text-shadow: 2px 2px 4px rgba(0, 0, 0, 1);
+ padding: 10px 10px 5px 10px;
+}
+
+.popup .amenity .usage {
+ width: 100%;
+ height: 80px;
+ line-height: 14px;
+ overflow: hidden;
+ color: rgb(170, 170, 170);
+ font-size: 18px;
+ text-align: left;
+ text-shadow: 2px 2px 4px rgba(0, 0, 0, 1);
+ padding: 5px 10px 5px 15px;
+ white-space: pre-line;
+}
+
+.popup .amenity>.items {
+ /* width: 100%; */
+ height: 390px;
+ background-color: rgba(48, 48, 48, 1.0);
+ /* overflow-y: auto; */
+ overflow-y: hidden;
+ overflow-x: hidden;
+ /* padding: 20px 20px 10px 15px; */
+ margin: 5px 20px 10px 15px;
+ border: 1px solid rgb(90, 90, 90);
+}
+
+.popup .amenity>.items table {
+ width: 100%;
+}
+
+.popup .amenity>.items .table tr {
+ width: 100%;
+ height: 130px;
+ /* background-color: rgb(0, 0, 128); */
+}
+
+.popup .amenity>.items div.products {
+ width: 100%;
+}
+
+.popup .amenity>.items div.products div#item_title {
+ width: 100%;
+ height: 30px;
+ font-size: 25px;
+ font-weight: bolder;
+ text-align: left;
+ white-space: nowrap;
+ text-overflow: ellipsis;
+ overflow: hidden;
+ color: rgba(192, 192, 192, 1.0);
+ text-shadow: 2px 2px 4px rgba(0, 0, 0, 1);
+ line-height: 28px;
+ margin: 5px 0px 0px 10px;
+}
+
+.popup .amenity>.items div.products div#thumb {
+ width: 182px;
+ height: 80px;
+ margin: 0px 5px 0px 10px;
+ display: inline-block;
+ vertical-align: top;
+}
+
+.popup .amenity>.items div.products div#details {
+ width: 142px;
+ height: 80px;
+ margin: 0px 5px 0px 5px;
+ display: inline-block;
+ vertical-align: top;
+ font-size: 18px;
+ color: rgb(170, 170, 170);
+ text-shadow: 2px 2px 4px rgba(0, 0, 0, 1);
+ /* background-color: rgba(124, 124, 0, 1); */
+}
+
+.popup .amenity>.items div.products div#freecnt_title {
+ width: 60%;
+ height: 50%;
+ display: inline-block;
+ vertical-align: top;
+ padding: 0px 10px 0px 0px;
+ text-align: right;
+ /* background-color: rgba(124, 124, 124, 1); */
+}
+
+.popup .amenity>.items div.products div#freecnt_val {
+ width: 40%;
+ height: 50%;
+ display: inline-block;
+ font-size: 30px;
+ padding: 0px 0px 0px 5px;
+ color: rgba(192, 192, 192, 1.0);
+ text-shadow: 2px 2px 4px rgba(0, 0, 0, 1);
+ /* background-color: rgba(200, 124, 124, 1); */
+}
+
+.popup .amenity>.items div.products div#price_title {
+ width: 60%;
+ height: 50%;
+ display: inline-block;
+ vertical-align: top;
+ text-align: right;
+ padding: 0px 10px 0px 0px;
+ /* background-color: rgba(200, 124, 200, 1); */
+}
+
+.popup .amenity>.items div.products div#price_val {
+ width: 40%;
+ height: 50%;
+ display: inline-block;
+ font-size: 30px;
+ padding: 0px 0px 0px 5px;
+ color: rgba(192, 192, 192, 1.0);
+ text-shadow: 2px 2px 4px rgba(0, 0, 0, 1);
+ /* background-color: rgba(200, 200, 124, 1); */
+}
+
+.popup .amenity>.items div.products div#quantity_val {
+ width: 90px;
+ height: 80px;
+ margin: 0px 0px 0px 5px;
+ display: inline-block;
+ vertical-align: top;
+ font-size: 68px;
+ line-height: 90px;
+ text-align: right;
+ color: rgba(190, 190, 190, 1);
+}
+
+.popup .amenity>.items .table tr.active {
+ background-color: rgba(67, 67, 67, 1);
+ box-shadow: 0px 0px 30px rgba(0, 0, 0, 1);
+}
+
+.popup .amenity>.items::-webkit-scrollbar {
+ width: 5px;
+ height: 8px;
+ background-color: #aaa;
+ /* or add it to the track */
+}
+
+.popup .amenity>div.buttons {
+ width: 100%;
+ height: 145px;
+ font-size: 28px;
+ text-align: center;
+ color: rgba(192, 192, 192, 1.0);
+ padding: 10px 20px 5px 20px;
+}
+
+.popup .amenity>div.buttons div {
+ height: 38px;
+ border: 1px solid rgb(90, 90, 90);
+}
+
+.popup .amenity>div.buttons .active {
+ border: 1px solid rgb(65, 196, 110);
+ font-size: 30px;
+ box-shadow: 0px 0px 30px rgba(0, 0, 0, 1);
+}
+
+.popup .amenity>div.buttons .order {
+ width: 100%;
+ border-radius: 5px;
+ margin: 0px 0px 5px 0px;
+}
+
+.popup .amenity>div.buttons .cancel {
+ width: 100%;
+ border-radius: 5px;
+ margin: 0px 0px 5px 0px;
+}
+
+.popup .amenity>div.buttons .details {
+ width: 100%;
+ border-radius: 5px;
+}
+
+.popup .amenity>div.order-details {
+ width: 100%;
+ height: 700px;
+ background-color: rgba(48, 48, 48, 1.0);
+}
+
+.popup .amenity>div.order-details>.usage {
+ height: 60px;
+}
+
+.popup .amenity>.order-details>.items {
+ /* width: 100%; */
+ height: 485px;
+ background-color: rgba(48, 48, 48, 1.0);
+ /* overflow-y: auto; */
+ overflow-y: hidden;
+ overflow-x: hidden;
+ /* padding: 20px 20px 10px 15px; */
+ margin: 5px 20px 10px 15px;
+ border: 1px solid rgb(90, 90, 90);
+}
+
+.popup .amenity>.order-details>.items table {
+ width: 100%;
+}
+
+.popup .amenity>.order-details>.items .table tr {
+ width: 100%;
+ height: 114px;
+ /* background-color: rgb(0, 0, 128); */
+}
+
+.popup .amenity>.order-details>.items div.products {
+ width: 100%;
+}
+
+.popup .amenity>.order-details>.items div.products div#order_num {
+ /* width: 100%; */
+ height: 28px;
+ font-size: 19px;
+ font-weight: bolder;
+ text-align: left;
+ white-space: nowrap;
+ text-overflow: ellipsis;
+ overflow: hidden;
+ color: rgba(192, 192, 192, 1.0);
+ /* text-shadow: 2px 2px 4px rgba(0, 0, 0, 1); */
+ line-height: 28px;
+ margin: 5px 10px 5px 10px;
+ border-bottom: solid;
+ border-bottom-color: rgb(255, 0, 0);
+}
+
+.popup .amenity>.order-details>.items div.products div#thumb {
+ width: 35%;
+ height: 72px;
+ margin: 0px 5px 0px 10px;
+ display: inline-block;
+ vertical-align: top;
+}
+
+.popup .amenity>.order-details>.items div.products div#summary {
+ width: 58%;
+ height: 69px;
+ margin: 0px 5px 0px 10px;
+ font-size: 18px;
+ color: rgba(190, 190, 190, 1);
+ display: inline-block;
+ vertical-align: top;
+}
+
+.popup .amenity>.order-details>.items div.products div#quantity_title {
+ width: 37%;
+ display: inline-block;
+ text-align: center;
+}
+
+.popup .amenity>.order-details>.items div.products div#amount_title {
+ width: 63%;
+ display: inline-block;
+ text-align: center;
+}
+
+.popup .amenity>.order-details>.items div.products div#quantity_val {
+ width: 37%;
+ height: 60px;
+ display: inline-block;
+ vertical-align: top;
+ font-size: 45px;
+ line-height: 60px;
+ text-align: center;
+ color: rgba(190, 190, 190, 1);
+}
+
+.popup .amenity>.order-details>.items div.products div#amount_val {
+ width: 63%;
+ height: 60px;
+ display: inline-block;
+ vertical-align: top;
+ font-size: 45px;
+ line-height: 60px;
+ text-align: center;
+ color: rgba(190, 190, 190, 1);
+}
+
+.popup .amenity>.order-details>.items .table tr.active {
+ background-color: rgba(67, 67, 67, 1);
+ box-shadow: 0px 0px 30px rgba(0, 0, 0, 1);
+}
+
+.popup .amenity>.order-details>.items::-webkit-scrollbar {
+ width: 5px;
+ height: 8px;
+ background-color: #aaa;
+ /* or add it to the track */
+}
+
+.popup .amenity>.order-details>.total_amount {
+ /* width: 100%; */
+ height: 75px;
+}
+
+.popup .amenity>.order-details>.total_amount .title {
+ width: 30%;
+ height: 64px;
+ display: inline-block;
+ vertical-align: top;
+ text-align: center;
+ margin: 0px 0px 0px 14px;
+}
+
+.popup .amenity>.order-details>.total_amount .value {
+ width: 56%;
+ height: 64px;
+ display: inline-block;
+ /* background-color: blue; */
+ text-align: center;
+ line-height: 55px;
+ text-align: center;
+ font-size: 55px;
+ color: rgba(190, 190, 190, 1);
+ text-shadow: 2px 2px 4px rgba(0, 0, 0, 1);
+ padding: 10px 10px 5px 10px;
+ margin: 0px 0px 0px 14px;
+}
+
+
+/* Room Service Style */
+
+.popup .roomservice {
+ position: absolute;
+ top: 96px;
+ left: -560px;
+ width: 1280px;
+ height: 700px;
+ overflow: hidden;
+ display: none;
+ /* background-color: rgba(47, 47, 47, 1); */
+ /* border-style: solid; */
+ /* border-color: rgb(96, 96, 96); */
+ filter: drop-shadow(0 0 10px rgba(255, 255, 255, 1));
+}
+
+.popup .roomservice .menu {
+ width: 496px;
+ height: 700px;
+ overflow: hidden;
+ display: inline-block;
+ background-color: rgba(67, 67, 67, 1);
+ border-style: solid;
+ border-color: rgb(96, 96, 96);
+ vertical-align: top;
+ /* filter: drop-shadow(0 0 10px rgba(255, 255, 255, 1)); */
+ background-color: rgba(67, 67, 67, 1);
+ /* box-shadow: 0px 0px 30px rgba(0, 0, 0, 1); */
+}
+
+.popup .roomservice .menu>.title {
+ width: 100%;
+ height: 64px;
+ line-height: 40px;
+ overflow: hidden;
+ color: rgb(247, 236, 234);
+ font-size: 40px;
+ text-align: left;
+ text-shadow: 2px 2px 4px rgba(0, 0, 0, 1);
+ padding: 10px 10px 5px 10px;
+}
+
+.popup .roomservice .menu>.usage {
+ width: 100%;
+ height: 80px;
+ line-height: 14px;
+ overflow: hidden;
+ color: rgb(170, 170, 170);
+ font-size: 18px;
+ text-align: left;
+ text-shadow: 2px 2px 4px rgba(0, 0, 0, 1);
+ padding: 5px 10px 5px 15px;
+ white-space: pre-line;
+}
+
+.popup .roomservice .menu>.items {
+ /* width: 100%; */
+ height: 390px;
+ background-color: rgba(48, 48, 48, 1.0);
+ /* overflow-y: auto; */
+ overflow-y: hidden;
+ overflow-x: hidden;
+ /* padding: 20px 20px 10px 15px; */
+ margin: 5px 20px 10px 15px;
+ border: 1px solid rgb(90, 90, 90);
+}
+
+.popup .roomservice .menu>.items table {
+ width: 100%;
+}
+
+.popup .roomservice .menu>.items .table tr {
+ width: 100%;
+ height: 106px;
+ /* background-color: rgb(0, 0, 128); */
+}
+
+.popup .roomservice .menu>.items div.products {
+ width: 100%;
+}
+
+.popup .roomservice .menu>.items div.products div#title {
+ width: 100%;
+ height: 30px;
+ font-size: 25px;
+ font-weight: bolder;
+ text-align: left;
+ white-space: nowrap;
+ text-overflow: ellipsis;
+ overflow: hidden;
+ color: rgba(192, 192, 192, 1.0);
+ text-shadow: 2px 2px 4px rgba(0, 0, 0, 1);
+ line-height: 28px;
+ margin: 5px 0px 0px 10px;
+}
+
+.popup .roomservice .menu>.items div.products div#details {
+ width: 100%;
+ height: 70px;
+ margin: 0px 5px 0px 5px;
+ display: block;
+ vertical-align: top;
+ font-size: 18px;
+ text-shadow: 2px 2px 4px rgba(0, 0, 0, 1);
+ /* background-color: rgba(124, 124, 0, 1); */
+}
+
+.popup .roomservice .menu>.items div.products div#price {
+ width: 65%;
+ font-size: 48px;
+ line-height: 70px;
+ display: inline-block;
+ vertical-align: top;
+ color: rgb(240, 190, 170);
+ padding: 0px 10px 0px 0px;
+ text-align: center;
+ /* background-color: rgba(124, 124, 124, 1); */
+}
+
+.popup .roomservice .menu>.items div.products div#quantity {
+ width: 34%;
+ display: inline-block;
+ text-align: right;
+ padding: 0px 0px 0px 5px;
+ text-shadow: 2px 2px 4px rgba(0, 0, 0, 1);
+ /* background-color: rgba(200, 124, 124, 1); */
+}
+
+.popup .roomservice .menu>.items div.products div#quantity #title {
+ display: inline-block;
+ vertical-align: middle;
+ font-size: 18px;
+ line-height: 18px;
+ text-align: center;
+ padding: 0px 0px 0px 0px;
+ margin: 0px;
+ /* background-color: rgba(200, 124, 200, 1); */
+}
+
+.popup .roomservice .menu>.items div.products div#quantity #value {
+ font-size: 40px;
+ line-height: 40px;
+ text-align: center;
+ color: rgba(220, 220, 220, 1.0);
+ /* background-color: rgba(200, 200, 124, 1); */
+}
+
+.popup .roomservice .menu>.items .table tr.active {
+ background-color: rgba(67, 67, 67, 1);
+ box-shadow: 0px 0px 30px rgba(0, 0, 0, 1);
+}
+
+.popup .roomservice .menu>.items::-webkit-scrollbar {
+ width: 5px;
+ height: 8px;
+ background-color: #aaa;
+ /* or add it to the track */
+}
+
+.popup .roomservice .menu>div.buttons {
+ width: 100%;
+ height: 145px;
+ font-size: 28px;
+ text-align: center;
+ color: rgba(192, 192, 192, 1.0);
+ padding: 10px 20px 5px 20px;
+}
+
+.popup .roomservice .menu>div.buttons div {
+ height: 38px;
+ border: 1px solid rgb(90, 90, 90);
+}
+
+.popup .roomservice .menu>div.buttons .active {
+ border: 1px solid rgb(65, 196, 110);
+ font-size: 30px;
+ box-shadow: 0px 0px 30px rgba(0, 0, 0, 1);
+}
+
+.popup .roomservice .menu>div.buttons .order {
+ width: 100%;
+ border-radius: 5px;
+ margin: 0px 0px 5px 0px;
+}
+
+.popup .roomservice .menu>div.buttons .cancel {
+ width: 100%;
+ border-radius: 5px;
+ margin: 0px 0px 5px 0px;
+}
+
+.popup .roomservice .menu>div.buttons .details {
+ width: 100%;
+ border-radius: 5px;
+}
+
+.popup .roomservice .menu>div.order-details {
+ width: 100%;
+ height: 700px;
+ background-color: rgba(48, 48, 48, 1.0);
+}
+
+.popup .roomservice .menu div.order-details>.title {
+ width: 100%;
+ height: 64px;
+ line-height: 40px;
+ overflow: hidden;
+ color: rgb(247, 236, 234);
+ font-size: 40px;
+ text-align: left;
+ text-shadow: 2px 2px 4px rgba(0, 0, 0, 1);
+ padding: 10px 10px 5px 10px;
+}
+
+.popup .roomservice .menu div.order-details>.usage {
+ width: 100%;
+ height: 60px;
+ line-height: 14px;
+ overflow: hidden;
+ color: rgb(170, 170, 170);
+ font-size: 18px;
+ text-align: left;
+ text-shadow: 2px 2px 4px rgba(0, 0, 0, 1);
+ padding: 5px 10px 5px 15px;
+ white-space: pre-line;
+}
+
+.popup .roomservice .menu>.order-details>.items {
+ /* width: 100%; */
+ height: 485px;
+ background-color: rgba(48, 48, 48, 1.0);
+ /* overflow-y: auto; */
+ overflow-y: hidden;
+ overflow-x: hidden;
+ /* padding: 20px 20px 10px 15px; */
+ margin: 5px 20px 10px 15px;
+ border: 1px solid rgb(90, 90, 90);
+}
+
+.popup .roomservice .menu>.order-details>.items table {
+ width: 100%;
+}
+
+.popup .roomservice .menu>.order-details>.items .table tr {
+ width: 100%;
+ height: 114px;
+ /* background-color: rgb(0, 0, 128); */
+}
+
+.popup .roomservice .menu>.order-details>.items div.products {
+ width: 100%;
+}
+
+.popup .roomservice .menu>.order-details>.items div.products div#order_num {
+ /* width: 100%; */
+ height: 28px;
+ font-size: 19px;
+ font-weight: bolder;
+ text-align: left;
+ white-space: nowrap;
+ text-overflow: ellipsis;
+ overflow: hidden;
+ color: rgba(192, 192, 192, 1.0);
+ /* text-shadow: 2px 2px 4px rgba(0, 0, 0, 1); */
+ line-height: 28px;
+ margin: 5px 10px 5px 10px;
+ border-bottom: solid;
+ border-bottom-color: rgb(255, 0, 0);
+}
+
+.popup .roomservice .menu>.order-details>.items div.products div#thumb {
+ width: 35%;
+ height: 72px;
+ margin: 0px 5px 0px 10px;
+ display: inline-block;
+ vertical-align: top;
+}
+
+.popup .roomservice .menu>.order-details>.items div.products div#summary {
+ width: 58%;
+ height: 69px;
+ margin: 0px 5px 0px 10px;
+ font-size: 18px;
+ color: rgba(190, 190, 190, 1);
+ display: inline-block;
+ vertical-align: top;
+}
+
+.popup .roomservice .menu>.order-details>.items div.products div#quantity_title {
+ width: 37%;
+ display: inline-block;
+ text-align: center;
+}
+
+.popup .roomservice .menu>.order-details>.items div.products div#amount_title {
+ width: 63%;
+ display: inline-block;
+ text-align: center;
+}
+
+.popup .roomservice .menu>.order-details>.items div.products div#quantity_val {
+ width: 37%;
+ height: 60px;
+ display: inline-block;
+ vertical-align: top;
+ font-size: 45px;
+ line-height: 60px;
+ text-align: center;
+ color: rgba(190, 190, 190, 1);
+}
+
+.popup .roomservice .menu>.order-details>.items div.products div#amount_val {
+ width: 63%;
+ height: 60px;
+ display: inline-block;
+ vertical-align: top;
+ font-size: 45px;
+ line-height: 60px;
+ text-align: center;
+ color: rgba(190, 190, 190, 1);
+}
+
+.popup .roomservice .menu>.order-details>.items .table tr.active {
+ background-color: rgba(67, 67, 67, 1);
+ box-shadow: 0px 0px 30px rgba(0, 0, 0, 1);
+}
+
+.popup .roomservice .menu>.order-details>.items::-webkit-scrollbar {
+ width: 5px;
+ height: 8px;
+ background-color: #aaa;
+ /* or add it to the track */
+}
+
+.popup .roomservice .menu>.order-details>.total_amount {
+ /* width: 100%; */
+ height: 75px;
+}
+
+.popup .roomservice .menu>.order-details>.total_amount .title {
+ width: 30%;
+ height: 64px;
+ display: inline-block;
+ vertical-align: top;
+ text-align: center;
+ margin: 0px 0px 0px 14px;
+ color: rgb(247, 236, 234);
+ font-size: 40px;
+}
+
+.popup .roomservice .menu>.order-details>.total_amount .value {
+ width: 56%;
+ height: 64px;
+ display: inline-block;
+ /* background-color: blue; */
+ text-align: center;
+ line-height: 55px;
+ text-align: center;
+ font-size: 55px;
+ color: rgba(190, 190, 190, 1);
+ text-shadow: 2px 2px 4px rgba(0, 0, 0, 1);
+ padding: 10px 10px 5px 10px;
+ margin: 0px 0px 0px 14px;
+}
+
+.popup .roomservice .description {
+ width: 760px;
+ height: 700px;
+ display: inline-block;
+ margin: 0px 0px 0px 20px;
+ /* background-color: rgba(46, 46, 46, 1.0); */
+}
+
+.popup .roomservice .description>.rstitle {
+ width: 100%;
+ height: 64px;
+ line-height: 40px;
+ overflow: hidden;
+ color: rgb(247, 236, 234);
+ font-size: 40px;
+ text-align: left;
+ text-shadow: 2px 2px 4px rgba(0, 0, 0, 1);
+ padding: 10px 10px 5px 10px;
+}
+
+.popup .roomservice .description>.rscomment {
+ width: 100%;
+ height: 60px;
+ line-height: 14px;
+ overflow: hidden;
+ color: rgb(170, 170, 170);
+ font-size: 18px;
+ text-align: left;
+ text-shadow: 2px 2px 4px rgba(0, 0, 0, 1);
+ padding: 5px 10px 5px 15px;
+ white-space: pre-line;
+}
+
+.popup .roomservice .description>.image {
+ width: 740px;
+ height: 100%;
+ background-repeat: no-repeat;
+ background-size: contain;
+ /* padding: 0px 30px 0px 0px; */
+ margin: 30px 0px 0px 0px;
+ /* display: block; */
+ filter: drop-shadow(0 0 10px rgba(0, 0, 0, 1));
+}
+
+
+/* MY PAGE Style */
+
+.popup>.mypage {
+ position: absolute;
+ width: 100%;
+ height: 100%;
+}
+
+.popup>.mypage>.message {
+ position: absolute;
+ top: 13%;
+ left: 6%;
+ width: 88%;
+ height: 80%;
+ background-color: rgb(64, 64, 64);
+ background-image: url(./images/bg_message_cream-paper.png);
+ box-shadow: 2px 3px 20px black, 0 0 200px rgb(16, 16, 16) inset;
+ overflow: hidden;
+ display: none;
+}
+
+.popup>.mypage>.message>#hotel_logo {
+ position: absolute;
+}
+
+.popup>.mypage>.message>#title {
+ max-height: 200px;
+ line-height: 200px;
+ color: rgb(255, 255, 255);
+ font-size: 48px;
+ text-align: center;
+ text-shadow: 2px 2px 4px rgba(0, 0, 0, 1)
+}
+
+.popup>.mypage>.message>#msg_ctz {
+ position: absolute;
+ top: 200px;
+ width: 100%;
+ height: 600px;
+ font-size: 28px;
+ line-height: 40px;
+ padding: 0px 20px 0px 20px;
+ color: rgb(235, 235, 235);
+ text-align: center;
+ text-shadow: 1px 1px 4px rgba(0, 0, 0, 1);
+}
+
+.popup>.mypage>.message>#btn_back {
+ position: absolute;
+ top: 820px;
+ left: 1542px;
+ width: 140px;
+ height: 36px;
+ line-height: 38px;
+ font-size: 28px;
+ font-family: LG Display-Regular;
+ color: rgb(255, 255, 255);
+ text-shadow: 3px 3px 15px rgba(0, 0, 0, 1);
+ background-color: rgba(0, 0, 0, 0.4);
+ padding-left: 50px;
+ border-radius: 5px;
+ text-align: center;
+ filter: drop-shadow(2px 2px 4px black);
+}
+
+.popup>.mypage>.message>#btn_back::before {
+ position: absolute;
+ content: '';
+ width: 48px;
+ height: 34px;
+ margin-left: -62px;
+ background-image: url(./images/icons/icon_btn_back.png);
+ background-repeat: no-repeat;
+ background-position: right center;
+ background-size: contain;
+ filter: drop-shadow(0 0 5px rgba(0, 0, 0, 1));
+}
\ No newline at end of file
diff --git a/procentric/application/hoteltv.app.full.sm.css b/procentric/application/hoteltv.app.full.sm.css
new file mode 100755
index 0000000..eeb74e8
--- /dev/null
+++ b/procentric/application/hoteltv.app.full.sm.css
@@ -0,0 +1,172 @@
+.main .sub {
+ position: absolute;
+ top: 1080px;
+ left: 0px;
+ width: 1920px;
+ height: 1080px;
+ background-color: black;
+ display: none;
+}
+
+.main .sub .bg {
+ position: absolute;
+ top: 0px;
+ left: 0%;
+ width: 100%;
+ height: 100%;
+ padding: 0px;
+ overflow: hidden;
+ display: block;
+}
+
+.main .sub .bg div#lst_smbg {
+ width: 100%;
+ height: 100%;
+ margin: 0;
+ padding: 0;
+}
+
+.main .sub .bg .owl-carousel .owl-stage-outer {
+ width: 100%;
+ height: 100%;
+ margin: 0;
+ padding: 0;
+}
+
+.main .sub .bg .owl-carousel .owl-stage-outer .owl-stage {
+ width: 100%;
+ height: 100%;
+ margin: 0;
+ padding: 0;
+}
+
+.main .sub .bg .owl-carousel .owl-stage-outer .owl-stage .owl-item {
+ width: 100%;
+ height: 100%;
+ margin: 0;
+ padding: 0;
+}
+
+.main .sub .bg div .item {
+ width: 100%;
+ height: 100%;
+ margin: 0;
+ padding: 0;
+}
+
+
+/* STEP[#003]: Define SUB-MENU SELECTOR FRAMES */
+
+.main .sub .slider {
+ position: absolute;
+ top: 864px;
+ left: 0px;
+ width: 1920px;
+ height: 170px;
+ padding-top: 50px;
+ overflow: hidden;
+ display: none;
+}
+
+.main .sub .slider div {
+ height: 120px;
+ max-height: 120px;
+ padding-left: 0;
+ margin: 0;
+}
+
+div#sm_item_title {
+ position: absolute;
+ top: 40px;
+ width: 100%;
+ height: 100%;
+ margin: 0;
+ padding: 0;
+ color: rgb(235, 235, 235);
+ font-size: 2.2vw;
+ white-space: nowrap;
+ text-align: center;
+}
+
+div#sm_item_icon {
+ margin: 0;
+ padding: 0;
+ display: block
+}
+
+
+/* OWL Sub Menu Selector Container */
+
+.main .sub .slider .owl-carousel .owl-item.active.focus div [id*="sm_item_icon"] {
+ background-image: var(--icon_focus);
+}
+
+.main .sub .slider .owl-carousel .owl-item.active[class*="unfocus"] div [id*="sm_item_icon"] {
+ background-image: var(--icon_unfocus);
+}
+
+.main .sub .slider .owl-carousel .owl-item.active.focus div [id*="sm_item_title"] {
+ transform: scale(1.2);
+}
+
+.main .sub .slider .owl-dots {
+ position: absolute;
+ top: -50px;
+ width: 100%;
+ align-content: center;
+}
+
+.main .sub .bg .bg_ctz_thumb_frame {
+ position: absolute;
+ top: 130px;
+ left: 1550px;
+ width: 360px;
+ height: 700px;
+ line-height: 50px;
+ /* background-color: rgba(30, 30, 30, 0.6);
+ filter: drop-shadow(0 0 12px rgba(0, 0, 0, 0.8));
+ border-radius: 8px;
+ border: solid rgb(181, 218, 16);
+ */
+ background-color: rgba(40, 40, 40, 0.6);
+ filter: drop-shadow(0 0 12px rgba(0, 0, 0, 0.8));
+ border-radius: 4px;
+ border: solid rgb(10, 10, 10);
+ overflow: hidden;
+}
+
+.main .sub .bg .bg_ctz_thumb_frame #bg_ctz_thumb_item {
+ width: 320px;
+ height: 180px;
+ float: left;
+ margin: 10px 20px 10px 20px;
+ filter: drop-shadow(0 0 10px rgba(235, 235, 235, 0.9));
+ border-radius: 6px;
+ text-align: center;
+ line-height: 50px;
+ font-size: 20px;
+ color: rgb(235, 235, 235);
+ border: 1px solid rgb(60, 60, 60);
+ display: inline;
+}
+
+.main .sub .bg .bg_ctz_thumb_frame #bg_ctz_thumb_title {
+ font-size: 30px;
+ margin-left: 20px;
+ color: rgb(235, 235, 235);
+}
+
+.main .sub .bg .bg_ctz_thumb_frame #bg_ctz_thumb_morenotice {
+ font-size: 22px;
+ margin: 20px 5px 10px 20px;
+ line-height: 50px;
+ overflow-wrap: break-word;
+ color: rgb(181, 218, 16);
+ animation: bg_ctz_thumb_morenotice_blinker 2s linear infinite;
+}
+
+@keyframes bg_ctz_thumb_morenotice_blinker {
+ 50% {
+ color: rgb(235, 235, 235);
+ }
+}
\ No newline at end of file
diff --git a/procentric/application/hoteltv.app.full.tv.css b/procentric/application/hoteltv.app.full.tv.css
new file mode 100755
index 0000000..de79e7a
--- /dev/null
+++ b/procentric/application/hoteltv.app.full.tv.css
@@ -0,0 +1,155 @@
+/* TV Menu */
+
+.main .tv {
+ position: absolute;
+ top: 1080px;
+ left: 0px;
+ width: 1920px;
+ height: 1080px;
+ background: url(tv:);
+}
+
+.main .tv .bg {
+ position: absolute;
+ top: 0px;
+ left: 0%;
+ width: 100%;
+ height: 100%;
+ padding: 0px;
+ background: url(tv:);
+ overflow: hidden;
+ display: none;
+}
+
+.main .tv .bg div#lst_tvCtgbg {
+ width: 100%;
+ height: 100%;
+ margin: 0;
+ padding: 0;
+}
+
+.main .tv .bg .owl-carousel .owl-stage-outer {
+ width: 780px;
+ height: 100%;
+ margin: 0;
+ padding: 0;
+}
+
+.main .tv .bg .owl-carousel .owl-stage-outer .owl-stage {
+ width: 100%;
+ height: 100%;
+ margin: 0;
+ padding: 0;
+}
+
+.main .tv .bg .owl-carousel .owl-stage-outer .owl-stage .owl-item .item {
+ position: absolute;
+ top: 116px;
+ /* left: 80px;
+ width: 1840px; */
+ height: 844px;
+ margin: 20px 20px 20px 20px;
+ padding: 5px 20px 5px 20px;
+ background-color: rgba(0, 0, 0, 0.4);
+ filter: drop-shadow(0 0 10px rgba(0, 0, 0, 1));
+ border: solid rgb(137, 139, 129);
+ border-radius: 10px;
+ /* background: linear-gradient(to left, rgba(0, 0, 0, 0), rgba(0, 0, 0, 0) 50%, rgba(120, 120, 120, 0.7) 70%, rgba(0, 0, 0, 0.7) 85%); */
+ overflow: hidden;
+}
+
+.main .tv .bg .owl-carousel .owl-stage-outer .item #tvctg_title {
+ line-height: 100px;
+ padding: 0;
+ margin: 0 0 10px 0;
+ font-size: 80px;
+ color: rgb(235, 235, 235);
+ white-space: nowrap;
+}
+
+.main .tv .bg .owl-carousel .owl-stage-outer .item .tvctg_chlist {
+ max-width: 680px;
+ height: 640px;
+ font-size: 32px;
+ overflow: hidden;
+}
+
+.main .tv .bg .owl-carousel .owl-stage-outer .item .tvctg_chlist .tvch_item_frame {
+ height: 110px;
+ margin: 10px 0 10px 0;
+ z-index: 1;
+}
+
+.main .tv .bg .owl-carousel .owl-stage-outer .item .tvctg_chlist .tvch_item_frame .tvch_epg {
+ float: left;
+ margin: 0 0 0 186px;
+}
+
+.main .tv .bg .owl-carousel .owl-stage-outer .item .tvctg_chlist .tvch_item_frame.focused .tvch_epg {
+ margin: 0 0 0 210px;
+}
+
+.main .tv .bg .owl-carousel .owl-stage-outer .item .tvctg_chlist .tvch_item_frame #tvch_epg_title {
+ font-size: 32px;
+ width: 468px;
+ color: rgb(255, 255, 255);
+ border-bottom: solid;
+ border-bottom-color: rgba(94, 90, 86, 0.8);
+ white-space: nowrap;
+ display: block;
+ overflow: hidden;
+}
+
+.main .tv .bg .owl-carousel .owl-stage-outer .item .tvctg_chlist .tvch_item_frame.focused #tvch_epg_title {
+ border-bottom-color: rgb(181, 218, 16);
+ color: rgb(181, 218, 16);
+ font-size: 40px;
+}
+
+.main .tv .bg .owl-carousel .owl-stage-outer .item .tvctg_chlist .tvch_item_frame #tvch_epg_title::before {
+ content: attr(ch_num);
+ font-size: 32px;
+ text-align: left;
+ margin: 20px 10px 0 0;
+ padding: 0 5px 0 5px;
+ color: rgb(10, 10, 10);
+ background-color: rgba(210, 210, 210, 1);
+ text-shadow: 0 0 5px rgba(68, 68, 68, 1), 0 0 20px rgba(10, 175, 230, 0);
+ border-radius: 5px;
+}
+
+.main .tv .bg .owl-carousel .owl-stage-outer .item .tvctg_chlist .tvch_item_frame #tvch_epg_info {
+ color: rgb(235, 235, 235);
+}
+
+.main .tv .bg .owl-carousel .owl-stage-outer .item .tvctg_chlist .tvch_item_frame #tvch_logo {
+ width: 176px;
+ height: 110px;
+ background-color: rgba(255, 255, 255, 1);
+ border-radius: 10px;
+}
+
+.main .tv .bg .owl-carousel .owl-stage-outer .item .tvctg_chlist .tvch_item_frame.focused #tvch_logo {
+ border: solid rgb(253, 55, 192);
+ transform: scale(1.14);
+ transform-origin: 2% 48%;
+ z-index: 2;
+}
+
+.main .tv .bg .owl-carousel .owl-stage-outer .item #tvctg_arrow_up {
+ width: 30px;
+ height: 30px;
+ margin: 10px 0 0 70px;
+ transform: rotate(-45deg) skew(15deg, 15deg);
+ border-top: 5px #fff solid;
+ border-right: 5px #fff solid;
+}
+
+.main .tv .bg .owl-carousel .owl-stage-outer .item #tvctg_arrow_down {
+ width: 30px;
+ height: 30px;
+ margin: 10px 0 0 70px;
+ transform: rotate(135deg) skew(15deg, 15deg);
+ border-top: 5px #fff solid;
+ border-right: 5px #fff solid;
+}
\ No newline at end of file
diff --git a/procentric/application/hoteltv.app.full.widjet.css b/procentric/application/hoteltv.app.full.widjet.css
new file mode 100755
index 0000000..5e99b34
--- /dev/null
+++ b/procentric/application/hoteltv.app.full.widjet.css
@@ -0,0 +1,109 @@
+/* STEP[#003]: Define WIDGET FRAMES */
+
+.widjet {
+ position: absolute;
+ top: 0px;
+ left: 0px;
+ width: 100%;
+ height: 100%;
+ padding: 0px;
+ overflow: hidden;
+ display: none;
+ text-shadow: 0 0 10px rgba(68, 68, 68, 1), 0 0 20px rgba(10, 175, 230, 0);
+ z-index: 2;
+}
+
+.widjet .top {
+ position: absolute;
+ top: 0px;
+ left: 0px;
+ width: 100%;
+ height: 100px;
+ /* background-color: rgba(0, 0, 0, 0.5); */
+ filter: drop-shadow(0 0px 5px rgba(0, 0, 0, 1));
+ padding: 0px;
+}
+
+
+/* SETP[#003-1]: Hotel Logo */
+
+.widjet .top .hotellogo {
+ position: absolute;
+ width: 300px;
+ height: 80px;
+ background-image: none;
+ background-size: contain;
+ background-repeat: no-repeat;
+ background-position: center center;
+ margin: 10px 0 4px 10px;
+ display: block;
+}
+
+
+/* SETP[#003-2]: Message */
+
+
+/* SETP[#003-3]: Weather */
+
+.widjet .top .weather {
+ position: absolute;
+ top: 7px;
+ left: 1420px;
+ height: 52px;
+ float: left;
+ background-image: none;
+ background-size: contain;
+ background-repeat: no-repeat;
+ display: block;
+}
+
+.widjet .top .weather #icon {
+ position: relative;
+ top: 8px;
+ left: 16px;
+ width: 80px;
+ height: 52px;
+ float: left;
+ background-image: none;
+ background-size: contain;
+ background-repeat: no-repeat;
+}
+
+.widjet .top .weather #temp {
+ position: relative;
+ left: 14px;
+ float: left;
+ font-size: 64px;
+ color: rgb(235, 235, 235);
+}
+
+
+/* SETP[#003-4]: Date&Time */
+
+.widjet .top .datetime {
+ position: absolute;
+ left: 1630px;
+ width: 270px;
+ height: 60px;
+ margin: 10px 30px 10px 0;
+ color: rgb(235, 235, 235);
+}
+
+.widjet .top .datetime p {
+ margin: 0;
+ padding: 0;
+}
+
+.widjet .top .datetime .time {
+ font-size: 52px;
+ line-height: 52px;
+ padding: 5px 0;
+ text-align: right;
+}
+
+.widjet .top .datetime .date {
+ letter-spacing: 0.1em;
+ font-size: 24px;
+ line-height: 24px;
+ text-align: right;
+}
\ No newline at end of file
diff --git a/procentric/application/hoteltv.error.css b/procentric/application/hoteltv.error.css
new file mode 100755
index 0000000..1e48003
--- /dev/null
+++ b/procentric/application/hoteltv.error.css
@@ -0,0 +1,16 @@
+/* ERROR WINDOW */
+
+.error {
+ position: absolute;
+ top: 0px;
+ left: 0px;
+ width: 1920px;
+ height: 1080px;
+ z-index: 10;
+ display: none;
+}
+
+.error .bg {
+ width: 100%;
+ height: 100%;
+}
\ No newline at end of file
diff --git a/procentric/application/hoteltv.ui_utils.css b/procentric/application/hoteltv.ui_utils.css
new file mode 100755
index 0000000..2db87db
--- /dev/null
+++ b/procentric/application/hoteltv.ui_utils.css
@@ -0,0 +1,108 @@
+.busy-frame {
+ position: absolute;
+ z-index: 10001;
+ top: 0;
+ left: 0;
+ width: 1920px;
+ height: 1080px;
+ padding: 0px;
+ background-color: rgba(0, 0, 0, 0.6);
+ display: none;
+}
+
+.busy-frame #busy_animation {
+ position: relative;
+ z-index: 10002;
+ top: 426px;
+ left: 874px;
+ width: 256px;
+ height: 256px;
+ padding: 0px;
+ display: none;
+}
+
+.busy-frame #busy_animation div {
+ transform-origin: 60px 80px;
+ animation: loading-spinner 1.2s linear infinite;
+}
+
+.busy-frame #busy_animation div:after {
+ content: " ";
+ display: block;
+ position: absolute;
+ top: 0px;
+ left: 60px;
+ width: 12px;
+ height: 28px;
+ border-radius: 5%;
+ background: #fff;
+}
+
+.busy-frame #busy_animation div:nth-child(1) {
+ transform: rotate(0deg);
+ animation-delay: -1.1s;
+}
+
+.busy-frame #busy_animation div:nth-child(2) {
+ transform: rotate(30deg);
+ animation-delay: -1s;
+}
+
+.busy-frame #busy_animation div:nth-child(3) {
+ transform: rotate(60deg);
+ animation-delay: -0.9s;
+}
+
+.busy-frame #busy_animation div:nth-child(4) {
+ transform: rotate(90deg);
+ animation-delay: -0.8s;
+}
+
+.busy-frame #busy_animation div:nth-child(5) {
+ transform: rotate(120deg);
+ animation-delay: -0.7s;
+}
+
+.busy-frame #busy_animation div:nth-child(6) {
+ transform: rotate(150deg);
+ animation-delay: -0.6s;
+}
+
+.busy-frame #busy_animation div:nth-child(7) {
+ transform: rotate(180deg);
+ animation-delay: -0.5s;
+}
+
+.busy-frame #busy_animation div:nth-child(8) {
+ transform: rotate(210deg);
+ animation-delay: -0.4s;
+}
+
+.busy-frame #busy_animation div:nth-child(9) {
+ transform: rotate(240deg);
+ animation-delay: -0.3s;
+}
+
+.busy-frame #busy_animation div:nth-child(10) {
+ transform: rotate(270deg);
+ animation-delay: -0.2s;
+}
+
+.busy-frame #busy_animation div:nth-child(11) {
+ transform: rotate(300deg);
+ animation-delay: -0.1s;
+}
+
+.busy-frame #busy_animation div:nth-child(12) {
+ transform: rotate(330deg);
+ animation-delay: 0s;
+}
+
+@keyframes loading-spinner {
+ 0% {
+ opacity: 1;
+ }
+ 100% {
+ opacity: 0;
+ }
+}
\ No newline at end of file
diff --git a/procentric/application/hoteltv.welcome.css b/procentric/application/hoteltv.welcome.css
new file mode 100755
index 0000000..ff73ce0
--- /dev/null
+++ b/procentric/application/hoteltv.welcome.css
@@ -0,0 +1,186 @@
+body {
+ overflow: hidden;
+}
+
+.welcome {
+ position: absolute;
+ top: 0px;
+ left: 0px;
+ width: 1920px;
+ height: 1080px;
+ padding: 0px;
+ display: none;
+ z-index: 1;
+}
+
+.startup {
+ top: 0px;
+ left: 0px;
+ position: absolute;
+ width: 100%;
+ height: 100%;
+ padding: 0px;
+ background-image: url(./images/hoteltv_service_preparing.png);
+ background-size: cover;
+ background-repeat: no-repeat;
+}
+
+.welcome .frame {
+ position: absolute;
+ top: 0px;
+ left: 0px;
+ width: 100%;
+ height: 100%;
+ padding: 0px;
+ background-color: rgba(0, 0, 0, 1);
+ background-image: none;
+ background-size: contain;
+ background-repeat: no-repeat;
+ display: none;
+}
+
+.welcome .frame .msgwin {
+ position: absolute;
+ top: 98px;
+ left: 519px;
+ width: 884px;
+ height: 648px;
+ padding: 0px;
+ background-image: url(./images/bg_language_welcome_box.png);
+ background-size: cover;
+ background-repeat: no-repeat;
+ border-radius: 11px;
+ filter: drop-shadow(0 0 20px rgba(0, 0, 0, 0.5));
+}
+
+.welcome .frame .msgwin #hotellogo {
+ position: absolute;
+ top: 108px;
+ left: 135px;
+ width: 634px;
+ height: 270px;
+ padding: 0px;
+ background-image: none;
+ background-size: contain;
+ background-repeat: no-repeat;
+ background-position: center;
+}
+
+.welcome .frame .msgwin #guestname {
+ position: absolute;
+ top: 486px;
+ left: 0px;
+ width: 884px;
+ height: 65px;
+ padding: 0px;
+ background-image: none;
+ background-size: contain;
+ background-repeat: no-repeat;
+ background-position: center;
+ font-size: 65px;
+ justify-content: center;
+ text-align: center;
+ color: rgb(235, 235, 235);
+ line-height: 65px;
+ max-width: 864px;
+ display: none;
+}
+
+.welcome .frame .msgwin #welcomemsg {
+ position: absolute;
+ top: 584px;
+ left: 0px;
+ width: 884px;
+ height: 44px;
+ padding: 0px;
+ background-image: none;
+ background-size: contain;
+ background-repeat: no-repeat;
+ background-position: center;
+ font-size: 33px;
+ justify-content: center;
+ text-align: center;
+ color: rgb(235, 235, 235);
+ line-height: 33px;
+ max-width: 864px;
+ display: none;
+}
+
+.welcome .frame .guide#langsel {
+ position: absolute;
+ top: 1037px;
+ left: 0px;
+ width: 1920px;
+ height: 54px;
+ background-color: rgba(0, 0, 0, 0.8);
+ display: inline-block;
+ color: rgba(200, 200, 200, 1);
+ font-size: 32px;
+ line-height: 43px;
+ text-align: center;
+ border-top: solid rgb(128, 128, 128);
+}
+
+.welcome #lst_langsel {
+ position: absolute;
+ top: 962px;
+ left: 0;
+ height: 76px;
+ line-height: 76px;
+ margin: 0;
+ padding: 0;
+ overflow: hidden;
+ display: none;
+}
+
+.welcome #lst_langsel .item {
+ color: rgba(200, 200, 200, 1);
+ font-size: 44px;
+ text-align: center;
+ background-repeat: no-repeat;
+ background-size: cover;
+}
+
+.welcome #lst_langsel .owl-item.active.center div {
+ background-image: var(--btn_focus);
+}
+
+.welcome #lst_langsel .owl-item.active div {
+ background-image: var(--btn_unfocus);
+}
+
+.control .skip_video {
+ z-index: 10000;
+ position: absolute;
+ z-index: 10000;
+ top: 927px;
+ left: 1579px;
+ width: 246px;
+ height: 68px;
+ padding: 0px;
+ background-color: rgba(0, 0, 0, 0.0);
+ background-image: none;
+ background-size: contain;
+ background-repeat: no-repeat;
+ display: none;
+}
+
+#debugwin {
+ z-index: 10000;
+ position: absolute;
+ top: 11px;
+ bottom: 22px;
+ right: 11px;
+ font-size: 12px;
+ background-color: rgba(18, 18, 18, 0.3);
+ text-align: left;
+ color: rgb(235, 235, 235);
+ line-height: 24px;
+ padding-left: 5px;
+ padding-top: 5px;
+ display: inline-flex;
+ max-width: 500px;
+ overflow-wrap: break-word;
+ word-wrap: break-word;
+ display: none;
+}
\ No newline at end of file
diff --git a/procentric/application/images/1280x720-01.jpg b/procentric/application/images/1280x720-01.jpg
new file mode 100755
index 0000000..90e317e
Binary files /dev/null and b/procentric/application/images/1280x720-01.jpg differ
diff --git a/procentric/application/images/1280x720-02.jpg b/procentric/application/images/1280x720-02.jpg
new file mode 100755
index 0000000..6163452
Binary files /dev/null and b/procentric/application/images/1280x720-02.jpg differ
diff --git a/procentric/application/images/1280x720-03.jpg b/procentric/application/images/1280x720-03.jpg
new file mode 100755
index 0000000..ded8064
Binary files /dev/null and b/procentric/application/images/1280x720-03.jpg differ
diff --git a/procentric/application/images/1280x720-04.jpg b/procentric/application/images/1280x720-04.jpg
new file mode 100755
index 0000000..f45d821
Binary files /dev/null and b/procentric/application/images/1280x720-04.jpg differ
diff --git a/procentric/application/images/1280x720-05.jpg b/procentric/application/images/1280x720-05.jpg
new file mode 100755
index 0000000..5577885
Binary files /dev/null and b/procentric/application/images/1280x720-05.jpg differ
diff --git a/procentric/application/images/1280x720-06.jpg b/procentric/application/images/1280x720-06.jpg
new file mode 100755
index 0000000..ec94797
Binary files /dev/null and b/procentric/application/images/1280x720-06.jpg differ
diff --git a/procentric/application/images/1920x1080-01.jpg b/procentric/application/images/1920x1080-01.jpg
new file mode 100755
index 0000000..d4422ab
Binary files /dev/null and b/procentric/application/images/1920x1080-01.jpg differ
diff --git a/procentric/application/images/1920x1080-02.jpg b/procentric/application/images/1920x1080-02.jpg
new file mode 100755
index 0000000..8bfa417
Binary files /dev/null and b/procentric/application/images/1920x1080-02.jpg differ
diff --git a/procentric/application/images/1920x1080-03.jpg b/procentric/application/images/1920x1080-03.jpg
new file mode 100755
index 0000000..5c33ca9
Binary files /dev/null and b/procentric/application/images/1920x1080-03.jpg differ
diff --git a/procentric/application/images/1920x1080-04.jpg b/procentric/application/images/1920x1080-04.jpg
new file mode 100755
index 0000000..13c8114
Binary files /dev/null and b/procentric/application/images/1920x1080-04.jpg differ
diff --git a/procentric/application/images/1920x1080-06.jpg b/procentric/application/images/1920x1080-06.jpg
new file mode 100755
index 0000000..76a1679
Binary files /dev/null and b/procentric/application/images/1920x1080-06.jpg differ
diff --git a/procentric/application/images/Altmetric_rgb.png b/procentric/application/images/Altmetric_rgb.png
new file mode 100755
index 0000000..27645d4
Binary files /dev/null and b/procentric/application/images/Altmetric_rgb.png differ
diff --git a/procentric/application/images/ani-busy-type01.gif b/procentric/application/images/ani-busy-type01.gif
new file mode 100755
index 0000000..d79dfe4
Binary files /dev/null and b/procentric/application/images/ani-busy-type01.gif differ
diff --git a/procentric/application/images/ani-busy-type02.gif b/procentric/application/images/ani-busy-type02.gif
new file mode 100755
index 0000000..a61f6a1
Binary files /dev/null and b/procentric/application/images/ani-busy-type02.gif differ
diff --git a/procentric/application/images/ani-busy-type03.gif b/procentric/application/images/ani-busy-type03.gif
new file mode 100755
index 0000000..c562b9f
Binary files /dev/null and b/procentric/application/images/ani-busy-type03.gif differ
diff --git a/procentric/application/images/bg_language_welcome_box.png b/procentric/application/images/bg_language_welcome_box.png
new file mode 100755
index 0000000..6917a56
Binary files /dev/null and b/procentric/application/images/bg_language_welcome_box.png differ
diff --git a/procentric/application/images/bg_message_cream-paper.png b/procentric/application/images/bg_message_cream-paper.png
new file mode 100755
index 0000000..9c6b2d1
Binary files /dev/null and b/procentric/application/images/bg_message_cream-paper.png differ
diff --git a/procentric/application/images/bg_message_detail.png b/procentric/application/images/bg_message_detail.png
new file mode 100755
index 0000000..57bb59d
Binary files /dev/null and b/procentric/application/images/bg_message_detail.png differ
diff --git a/procentric/application/images/bg_tv_category.png b/procentric/application/images/bg_tv_category.png
new file mode 100755
index 0000000..0d9a6ef
Binary files /dev/null and b/procentric/application/images/bg_tv_category.png differ
diff --git a/procentric/application/images/bg_weather_default.jpg b/procentric/application/images/bg_weather_default.jpg
new file mode 100755
index 0000000..5b1e26f
Binary files /dev/null and b/procentric/application/images/bg_weather_default.jpg differ
diff --git a/procentric/application/images/bt_language_tab_focus.png b/procentric/application/images/bt_language_tab_focus.png
new file mode 100755
index 0000000..b9835e8
Binary files /dev/null and b/procentric/application/images/bt_language_tab_focus.png differ
diff --git a/procentric/application/images/bt_language_tab_unfocus.png b/procentric/application/images/bt_language_tab_unfocus.png
new file mode 100755
index 0000000..8e6bab8
Binary files /dev/null and b/procentric/application/images/bt_language_tab_unfocus.png differ
diff --git a/procentric/application/images/bt_skip_ch01.png b/procentric/application/images/bt_skip_ch01.png
new file mode 100755
index 0000000..61f13b0
Binary files /dev/null and b/procentric/application/images/bt_skip_ch01.png differ
diff --git a/procentric/application/images/bt_skip_ch02.png b/procentric/application/images/bt_skip_ch02.png
new file mode 100755
index 0000000..70bd423
Binary files /dev/null and b/procentric/application/images/bt_skip_ch02.png differ
diff --git a/procentric/application/images/bt_skip_en.png b/procentric/application/images/bt_skip_en.png
new file mode 100755
index 0000000..fde457e
Binary files /dev/null and b/procentric/application/images/bt_skip_en.png differ
diff --git a/procentric/application/images/bt_skip_jp.png b/procentric/application/images/bt_skip_jp.png
new file mode 100755
index 0000000..d3a7803
Binary files /dev/null and b/procentric/application/images/bt_skip_jp.png differ
diff --git a/procentric/application/images/bt_skip_ko.png b/procentric/application/images/bt_skip_ko.png
new file mode 100755
index 0000000..96b2686
Binary files /dev/null and b/procentric/application/images/bt_skip_ko.png differ
diff --git a/procentric/application/images/btn_mm_focus-art.png b/procentric/application/images/btn_mm_focus-art.png
new file mode 100755
index 0000000..b29472a
Binary files /dev/null and b/procentric/application/images/btn_mm_focus-art.png differ
diff --git a/procentric/application/images/btn_mm_focus-flight.png b/procentric/application/images/btn_mm_focus-flight.png
new file mode 100755
index 0000000..777844b
Binary files /dev/null and b/procentric/application/images/btn_mm_focus-flight.png differ
diff --git a/procentric/application/images/btn_mm_focus-jeju.png b/procentric/application/images/btn_mm_focus-jeju.png
new file mode 100755
index 0000000..be35462
Binary files /dev/null and b/procentric/application/images/btn_mm_focus-jeju.png differ
diff --git a/procentric/application/images/btn_mm_focus-mypage.png b/procentric/application/images/btn_mm_focus-mypage.png
new file mode 100755
index 0000000..92a00ad
Binary files /dev/null and b/procentric/application/images/btn_mm_focus-mypage.png differ
diff --git a/procentric/application/images/btn_mm_focus-resort.png b/procentric/application/images/btn_mm_focus-resort.png
new file mode 100755
index 0000000..3b9ac5e
Binary files /dev/null and b/procentric/application/images/btn_mm_focus-resort.png differ
diff --git a/procentric/application/images/btn_mm_focus-rewards.png b/procentric/application/images/btn_mm_focus-rewards.png
new file mode 100755
index 0000000..2241d62
Binary files /dev/null and b/procentric/application/images/btn_mm_focus-rewards.png differ
diff --git a/procentric/application/images/btn_mm_focus-tv.png b/procentric/application/images/btn_mm_focus-tv.png
new file mode 100755
index 0000000..bf53c19
Binary files /dev/null and b/procentric/application/images/btn_mm_focus-tv.png differ
diff --git a/procentric/application/images/btn_mm_focus-weather.png b/procentric/application/images/btn_mm_focus-weather.png
new file mode 100755
index 0000000..7a36e65
Binary files /dev/null and b/procentric/application/images/btn_mm_focus-weather.png differ
diff --git a/procentric/application/images/btn_mm_focus.png b/procentric/application/images/btn_mm_focus.png
new file mode 100755
index 0000000..7bc4b6b
Binary files /dev/null and b/procentric/application/images/btn_mm_focus.png differ
diff --git a/procentric/application/images/btn_mm_unfocus-art.png b/procentric/application/images/btn_mm_unfocus-art.png
new file mode 100755
index 0000000..f3419bb
Binary files /dev/null and b/procentric/application/images/btn_mm_unfocus-art.png differ
diff --git a/procentric/application/images/btn_mm_unfocus-flight.png b/procentric/application/images/btn_mm_unfocus-flight.png
new file mode 100755
index 0000000..d2c8617
Binary files /dev/null and b/procentric/application/images/btn_mm_unfocus-flight.png differ
diff --git a/procentric/application/images/btn_mm_unfocus-jeju.png b/procentric/application/images/btn_mm_unfocus-jeju.png
new file mode 100755
index 0000000..7b6cba6
Binary files /dev/null and b/procentric/application/images/btn_mm_unfocus-jeju.png differ
diff --git a/procentric/application/images/btn_mm_unfocus-mypage.png b/procentric/application/images/btn_mm_unfocus-mypage.png
new file mode 100755
index 0000000..fe81103
Binary files /dev/null and b/procentric/application/images/btn_mm_unfocus-mypage.png differ
diff --git a/procentric/application/images/btn_mm_unfocus-resort.png b/procentric/application/images/btn_mm_unfocus-resort.png
new file mode 100755
index 0000000..e6490ee
Binary files /dev/null and b/procentric/application/images/btn_mm_unfocus-resort.png differ
diff --git a/procentric/application/images/btn_mm_unfocus-rewards.png b/procentric/application/images/btn_mm_unfocus-rewards.png
new file mode 100755
index 0000000..e645f09
Binary files /dev/null and b/procentric/application/images/btn_mm_unfocus-rewards.png differ
diff --git a/procentric/application/images/btn_mm_unfocus-tv.png b/procentric/application/images/btn_mm_unfocus-tv.png
new file mode 100755
index 0000000..d59d62c
Binary files /dev/null and b/procentric/application/images/btn_mm_unfocus-tv.png differ
diff --git a/procentric/application/images/btn_mm_unfocus-weather.png b/procentric/application/images/btn_mm_unfocus-weather.png
new file mode 100755
index 0000000..e659593
Binary files /dev/null and b/procentric/application/images/btn_mm_unfocus-weather.png differ
diff --git a/procentric/application/images/btn_mm_unfocus.png b/procentric/application/images/btn_mm_unfocus.png
new file mode 100755
index 0000000..a859e03
Binary files /dev/null and b/procentric/application/images/btn_mm_unfocus.png differ
diff --git a/procentric/application/images/hoteltv_service_error.png b/procentric/application/images/hoteltv_service_error.png
new file mode 100755
index 0000000..82a801f
Binary files /dev/null and b/procentric/application/images/hoteltv_service_error.png differ
diff --git a/procentric/application/images/hoteltv_service_preparing.png b/procentric/application/images/hoteltv_service_preparing.png
new file mode 100755
index 0000000..6c86194
Binary files /dev/null and b/procentric/application/images/hoteltv_service_preparing.png differ
diff --git a/procentric/application/images/icons/icon_btn_back.png b/procentric/application/images/icons/icon_btn_back.png
new file mode 100755
index 0000000..2995f72
Binary files /dev/null and b/procentric/application/images/icons/icon_btn_back.png differ
diff --git a/procentric/application/images/icons/icon_btn_media_play.png b/procentric/application/images/icons/icon_btn_media_play.png
new file mode 100755
index 0000000..bde47a8
Binary files /dev/null and b/procentric/application/images/icons/icon_btn_media_play.png differ
diff --git a/procentric/application/images/icons/icon_btn_media_stop.png b/procentric/application/images/icons/icon_btn_media_stop.png
new file mode 100755
index 0000000..f033e6f
Binary files /dev/null and b/procentric/application/images/icons/icon_btn_media_stop.png differ
diff --git a/procentric/application/images/icons/icon_btn_movie_play.png b/procentric/application/images/icons/icon_btn_movie_play.png
new file mode 100755
index 0000000..27b3524
Binary files /dev/null and b/procentric/application/images/icons/icon_btn_movie_play.png differ
diff --git a/procentric/application/images/icons/icon_contact_phone_48x48.png b/procentric/application/images/icons/icon_contact_phone_48x48.png
new file mode 100755
index 0000000..ce0f5e0
Binary files /dev/null and b/procentric/application/images/icons/icon_contact_phone_48x48.png differ
diff --git a/procentric/application/images/icons/icon_contact_phone_96x96.png b/procentric/application/images/icons/icon_contact_phone_96x96.png
new file mode 100755
index 0000000..28f7c8a
Binary files /dev/null and b/procentric/application/images/icons/icon_contact_phone_96x96.png differ
diff --git a/procentric/application/images/icons/icon_cotact_email_48x48.png b/procentric/application/images/icons/icon_cotact_email_48x48.png
new file mode 100755
index 0000000..1e90f3a
Binary files /dev/null and b/procentric/application/images/icons/icon_cotact_email_48x48.png differ
diff --git a/procentric/application/images/icons/icon_cotact_email_96x96.png b/procentric/application/images/icons/icon_cotact_email_96x96.png
new file mode 100755
index 0000000..de2d2c6
Binary files /dev/null and b/procentric/application/images/icons/icon_cotact_email_96x96.png differ
diff --git a/procentric/application/images/icons/icon_humidity.png b/procentric/application/images/icons/icon_humidity.png
new file mode 100755
index 0000000..7fa4996
Binary files /dev/null and b/procentric/application/images/icons/icon_humidity.png differ
diff --git a/procentric/application/images/icons/icon_loading_256x256.png b/procentric/application/images/icons/icon_loading_256x256.png
new file mode 100755
index 0000000..d28c5e4
Binary files /dev/null and b/procentric/application/images/icons/icon_loading_256x256.png differ
diff --git a/procentric/application/images/icons/icon_mypage_title.png b/procentric/application/images/icons/icon_mypage_title.png
new file mode 100755
index 0000000..eb1a707
Binary files /dev/null and b/procentric/application/images/icons/icon_mypage_title.png differ
diff --git a/procentric/application/images/icons/icon_place_48x48.png b/procentric/application/images/icons/icon_place_48x48.png
new file mode 100755
index 0000000..59bbe38
Binary files /dev/null and b/procentric/application/images/icons/icon_place_48x48.png differ
diff --git a/procentric/application/images/icons/icon_place_96x96.png b/procentric/application/images/icons/icon_place_96x96.png
new file mode 100755
index 0000000..cd1b8f2
Binary files /dev/null and b/procentric/application/images/icons/icon_place_96x96.png differ
diff --git a/procentric/application/images/icons/icon_read_message_48x48.png b/procentric/application/images/icons/icon_read_message_48x48.png
new file mode 100755
index 0000000..cd4e5a9
Binary files /dev/null and b/procentric/application/images/icons/icon_read_message_48x48.png differ
diff --git a/procentric/application/images/icons/icon_unread_message_48x48.png b/procentric/application/images/icons/icon_unread_message_48x48.png
new file mode 100755
index 0000000..1e90f3a
Binary files /dev/null and b/procentric/application/images/icons/icon_unread_message_48x48.png differ
diff --git a/procentric/application/images/icons/icon_wind.png b/procentric/application/images/icons/icon_wind.png
new file mode 100755
index 0000000..060f171
Binary files /dev/null and b/procentric/application/images/icons/icon_wind.png differ
diff --git a/procentric/application/images/language_screen_under_bar_note_text_chn.png b/procentric/application/images/language_screen_under_bar_note_text_chn.png
new file mode 100755
index 0000000..4293cc3
Binary files /dev/null and b/procentric/application/images/language_screen_under_bar_note_text_chn.png differ
diff --git a/procentric/application/images/language_screen_under_bar_note_text_eng.png b/procentric/application/images/language_screen_under_bar_note_text_eng.png
new file mode 100755
index 0000000..de30811
Binary files /dev/null and b/procentric/application/images/language_screen_under_bar_note_text_eng.png differ
diff --git a/procentric/application/images/language_screen_under_bar_note_text_hk.png b/procentric/application/images/language_screen_under_bar_note_text_hk.png
new file mode 100755
index 0000000..84b93dc
Binary files /dev/null and b/procentric/application/images/language_screen_under_bar_note_text_hk.png differ
diff --git a/procentric/application/images/language_screen_under_bar_note_text_jpn.png b/procentric/application/images/language_screen_under_bar_note_text_jpn.png
new file mode 100755
index 0000000..bbf2a89
Binary files /dev/null and b/procentric/application/images/language_screen_under_bar_note_text_jpn.png differ
diff --git a/procentric/application/images/language_screen_under_bar_note_text_kor.png b/procentric/application/images/language_screen_under_bar_note_text_kor.png
new file mode 100755
index 0000000..4e3cc9f
Binary files /dev/null and b/procentric/application/images/language_screen_under_bar_note_text_kor.png differ
diff --git a/procentric/application/images/wallpaper-1280x720-welcome1.jpg b/procentric/application/images/wallpaper-1280x720-welcome1.jpg
new file mode 100755
index 0000000..6dc3e58
Binary files /dev/null and b/procentric/application/images/wallpaper-1280x720-welcome1.jpg differ
diff --git a/procentric/application/images/wallpaper-1280x720-welcome2.jpg b/procentric/application/images/wallpaper-1280x720-welcome2.jpg
new file mode 100755
index 0000000..becba4e
Binary files /dev/null and b/procentric/application/images/wallpaper-1280x720-welcome2.jpg differ
diff --git a/procentric/application/images/weather.zip b/procentric/application/images/weather.zip
new file mode 100755
index 0000000..2485419
Binary files /dev/null and b/procentric/application/images/weather.zip differ
diff --git a/procentric/application/images/weather/top_bar_weather_icon_0.png b/procentric/application/images/weather/top_bar_weather_icon_0.png
new file mode 100755
index 0000000..4898d9f
Binary files /dev/null and b/procentric/application/images/weather/top_bar_weather_icon_0.png differ
diff --git a/procentric/application/images/weather/top_bar_weather_icon_1.png b/procentric/application/images/weather/top_bar_weather_icon_1.png
new file mode 100755
index 0000000..4898d9f
Binary files /dev/null and b/procentric/application/images/weather/top_bar_weather_icon_1.png differ
diff --git a/procentric/application/images/weather/top_bar_weather_icon_10.png b/procentric/application/images/weather/top_bar_weather_icon_10.png
new file mode 100755
index 0000000..c9ea8b2
Binary files /dev/null and b/procentric/application/images/weather/top_bar_weather_icon_10.png differ
diff --git a/procentric/application/images/weather/top_bar_weather_icon_11.png b/procentric/application/images/weather/top_bar_weather_icon_11.png
new file mode 100755
index 0000000..8ce1ee2
Binary files /dev/null and b/procentric/application/images/weather/top_bar_weather_icon_11.png differ
diff --git a/procentric/application/images/weather/top_bar_weather_icon_12.png b/procentric/application/images/weather/top_bar_weather_icon_12.png
new file mode 100755
index 0000000..eb29cb0
Binary files /dev/null and b/procentric/application/images/weather/top_bar_weather_icon_12.png differ
diff --git a/procentric/application/images/weather/top_bar_weather_icon_13.png b/procentric/application/images/weather/top_bar_weather_icon_13.png
new file mode 100755
index 0000000..cb9f5fd
Binary files /dev/null and b/procentric/application/images/weather/top_bar_weather_icon_13.png differ
diff --git a/procentric/application/images/weather/top_bar_weather_icon_14.png b/procentric/application/images/weather/top_bar_weather_icon_14.png
new file mode 100755
index 0000000..5ccb24b
Binary files /dev/null and b/procentric/application/images/weather/top_bar_weather_icon_14.png differ
diff --git a/procentric/application/images/weather/top_bar_weather_icon_15.png b/procentric/application/images/weather/top_bar_weather_icon_15.png
new file mode 100755
index 0000000..cf1f7a9
Binary files /dev/null and b/procentric/application/images/weather/top_bar_weather_icon_15.png differ
diff --git a/procentric/application/images/weather/top_bar_weather_icon_16.png b/procentric/application/images/weather/top_bar_weather_icon_16.png
new file mode 100755
index 0000000..787435d
Binary files /dev/null and b/procentric/application/images/weather/top_bar_weather_icon_16.png differ
diff --git a/procentric/application/images/weather/top_bar_weather_icon_17.png b/procentric/application/images/weather/top_bar_weather_icon_17.png
new file mode 100755
index 0000000..970b16c
Binary files /dev/null and b/procentric/application/images/weather/top_bar_weather_icon_17.png differ
diff --git a/procentric/application/images/weather/top_bar_weather_icon_18.png b/procentric/application/images/weather/top_bar_weather_icon_18.png
new file mode 100755
index 0000000..a0b735f
Binary files /dev/null and b/procentric/application/images/weather/top_bar_weather_icon_18.png differ
diff --git a/procentric/application/images/weather/top_bar_weather_icon_19.png b/procentric/application/images/weather/top_bar_weather_icon_19.png
new file mode 100755
index 0000000..a6a658b
Binary files /dev/null and b/procentric/application/images/weather/top_bar_weather_icon_19.png differ
diff --git a/procentric/application/images/weather/top_bar_weather_icon_2.png b/procentric/application/images/weather/top_bar_weather_icon_2.png
new file mode 100755
index 0000000..1ec2128
Binary files /dev/null and b/procentric/application/images/weather/top_bar_weather_icon_2.png differ
diff --git a/procentric/application/images/weather/top_bar_weather_icon_20.png b/procentric/application/images/weather/top_bar_weather_icon_20.png
new file mode 100755
index 0000000..67a246f
Binary files /dev/null and b/procentric/application/images/weather/top_bar_weather_icon_20.png differ
diff --git a/procentric/application/images/weather/top_bar_weather_icon_21.png b/procentric/application/images/weather/top_bar_weather_icon_21.png
new file mode 100755
index 0000000..67a246f
Binary files /dev/null and b/procentric/application/images/weather/top_bar_weather_icon_21.png differ
diff --git a/procentric/application/images/weather/top_bar_weather_icon_22.png b/procentric/application/images/weather/top_bar_weather_icon_22.png
new file mode 100755
index 0000000..4ed1626
Binary files /dev/null and b/procentric/application/images/weather/top_bar_weather_icon_22.png differ
diff --git a/procentric/application/images/weather/top_bar_weather_icon_23.png b/procentric/application/images/weather/top_bar_weather_icon_23.png
new file mode 100755
index 0000000..ea7dd17
Binary files /dev/null and b/procentric/application/images/weather/top_bar_weather_icon_23.png differ
diff --git a/procentric/application/images/weather/top_bar_weather_icon_24.png b/procentric/application/images/weather/top_bar_weather_icon_24.png
new file mode 100755
index 0000000..ea7dd17
Binary files /dev/null and b/procentric/application/images/weather/top_bar_weather_icon_24.png differ
diff --git a/procentric/application/images/weather/top_bar_weather_icon_25.png b/procentric/application/images/weather/top_bar_weather_icon_25.png
new file mode 100755
index 0000000..98e9be1
Binary files /dev/null and b/procentric/application/images/weather/top_bar_weather_icon_25.png differ
diff --git a/procentric/application/images/weather/top_bar_weather_icon_26.png b/procentric/application/images/weather/top_bar_weather_icon_26.png
new file mode 100755
index 0000000..a4a8fc6
Binary files /dev/null and b/procentric/application/images/weather/top_bar_weather_icon_26.png differ
diff --git a/procentric/application/images/weather/top_bar_weather_icon_27.png b/procentric/application/images/weather/top_bar_weather_icon_27.png
new file mode 100755
index 0000000..a6e0efe
Binary files /dev/null and b/procentric/application/images/weather/top_bar_weather_icon_27.png differ
diff --git a/procentric/application/images/weather/top_bar_weather_icon_28.png b/procentric/application/images/weather/top_bar_weather_icon_28.png
new file mode 100755
index 0000000..31b4797
Binary files /dev/null and b/procentric/application/images/weather/top_bar_weather_icon_28.png differ
diff --git a/procentric/application/images/weather/top_bar_weather_icon_29.png b/procentric/application/images/weather/top_bar_weather_icon_29.png
new file mode 100755
index 0000000..2f9ca97
Binary files /dev/null and b/procentric/application/images/weather/top_bar_weather_icon_29.png differ
diff --git a/procentric/application/images/weather/top_bar_weather_icon_3.png b/procentric/application/images/weather/top_bar_weather_icon_3.png
new file mode 100755
index 0000000..bbf6f85
Binary files /dev/null and b/procentric/application/images/weather/top_bar_weather_icon_3.png differ
diff --git a/procentric/application/images/weather/top_bar_weather_icon_30.png b/procentric/application/images/weather/top_bar_weather_icon_30.png
new file mode 100755
index 0000000..0a68e8a
Binary files /dev/null and b/procentric/application/images/weather/top_bar_weather_icon_30.png differ
diff --git a/procentric/application/images/weather/top_bar_weather_icon_31.png b/procentric/application/images/weather/top_bar_weather_icon_31.png
new file mode 100755
index 0000000..57ec21a
Binary files /dev/null and b/procentric/application/images/weather/top_bar_weather_icon_31.png differ
diff --git a/procentric/application/images/weather/top_bar_weather_icon_32.png b/procentric/application/images/weather/top_bar_weather_icon_32.png
new file mode 100755
index 0000000..b6aae46
Binary files /dev/null and b/procentric/application/images/weather/top_bar_weather_icon_32.png differ
diff --git a/procentric/application/images/weather/top_bar_weather_icon_33.png b/procentric/application/images/weather/top_bar_weather_icon_33.png
new file mode 100755
index 0000000..57ec21a
Binary files /dev/null and b/procentric/application/images/weather/top_bar_weather_icon_33.png differ
diff --git a/procentric/application/images/weather/top_bar_weather_icon_34.png b/procentric/application/images/weather/top_bar_weather_icon_34.png
new file mode 100755
index 0000000..e58b342
Binary files /dev/null and b/procentric/application/images/weather/top_bar_weather_icon_34.png differ
diff --git a/procentric/application/images/weather/top_bar_weather_icon_35.png b/procentric/application/images/weather/top_bar_weather_icon_35.png
new file mode 100755
index 0000000..a19a541
Binary files /dev/null and b/procentric/application/images/weather/top_bar_weather_icon_35.png differ
diff --git a/procentric/application/images/weather/top_bar_weather_icon_36.png b/procentric/application/images/weather/top_bar_weather_icon_36.png
new file mode 100755
index 0000000..ef60543
Binary files /dev/null and b/procentric/application/images/weather/top_bar_weather_icon_36.png differ
diff --git a/procentric/application/images/weather/top_bar_weather_icon_37.png b/procentric/application/images/weather/top_bar_weather_icon_37.png
new file mode 100755
index 0000000..b632f41
Binary files /dev/null and b/procentric/application/images/weather/top_bar_weather_icon_37.png differ
diff --git a/procentric/application/images/weather/top_bar_weather_icon_38.png b/procentric/application/images/weather/top_bar_weather_icon_38.png
new file mode 100755
index 0000000..13724f7
Binary files /dev/null and b/procentric/application/images/weather/top_bar_weather_icon_38.png differ
diff --git a/procentric/application/images/weather/top_bar_weather_icon_39.png b/procentric/application/images/weather/top_bar_weather_icon_39.png
new file mode 100755
index 0000000..4e6adae
Binary files /dev/null and b/procentric/application/images/weather/top_bar_weather_icon_39.png differ
diff --git a/procentric/application/images/weather/top_bar_weather_icon_4.png b/procentric/application/images/weather/top_bar_weather_icon_4.png
new file mode 100755
index 0000000..e170368
Binary files /dev/null and b/procentric/application/images/weather/top_bar_weather_icon_4.png differ
diff --git a/procentric/application/images/weather/top_bar_weather_icon_40.png b/procentric/application/images/weather/top_bar_weather_icon_40.png
new file mode 100755
index 0000000..930f727
Binary files /dev/null and b/procentric/application/images/weather/top_bar_weather_icon_40.png differ
diff --git a/procentric/application/images/weather/top_bar_weather_icon_41.png b/procentric/application/images/weather/top_bar_weather_icon_41.png
new file mode 100755
index 0000000..5c39733
Binary files /dev/null and b/procentric/application/images/weather/top_bar_weather_icon_41.png differ
diff --git a/procentric/application/images/weather/top_bar_weather_icon_42.png b/procentric/application/images/weather/top_bar_weather_icon_42.png
new file mode 100755
index 0000000..627c121
Binary files /dev/null and b/procentric/application/images/weather/top_bar_weather_icon_42.png differ
diff --git a/procentric/application/images/weather/top_bar_weather_icon_43.png b/procentric/application/images/weather/top_bar_weather_icon_43.png
new file mode 100755
index 0000000..f8299f2
Binary files /dev/null and b/procentric/application/images/weather/top_bar_weather_icon_43.png differ
diff --git a/procentric/application/images/weather/top_bar_weather_icon_44.png b/procentric/application/images/weather/top_bar_weather_icon_44.png
new file mode 100755
index 0000000..0529f39
Binary files /dev/null and b/procentric/application/images/weather/top_bar_weather_icon_44.png differ
diff --git a/procentric/application/images/weather/top_bar_weather_icon_45.png b/procentric/application/images/weather/top_bar_weather_icon_45.png
new file mode 100755
index 0000000..0f671c9
Binary files /dev/null and b/procentric/application/images/weather/top_bar_weather_icon_45.png differ
diff --git a/procentric/application/images/weather/top_bar_weather_icon_46.png b/procentric/application/images/weather/top_bar_weather_icon_46.png
new file mode 100755
index 0000000..a7ca5d2
Binary files /dev/null and b/procentric/application/images/weather/top_bar_weather_icon_46.png differ
diff --git a/procentric/application/images/weather/top_bar_weather_icon_47.png b/procentric/application/images/weather/top_bar_weather_icon_47.png
new file mode 100755
index 0000000..1704bd0
Binary files /dev/null and b/procentric/application/images/weather/top_bar_weather_icon_47.png differ
diff --git a/procentric/application/images/weather/top_bar_weather_icon_48.png b/procentric/application/images/weather/top_bar_weather_icon_48.png
new file mode 100755
index 0000000..c225d3c
Binary files /dev/null and b/procentric/application/images/weather/top_bar_weather_icon_48.png differ
diff --git a/procentric/application/images/weather/top_bar_weather_icon_5.png b/procentric/application/images/weather/top_bar_weather_icon_5.png
new file mode 100755
index 0000000..8d81cce
Binary files /dev/null and b/procentric/application/images/weather/top_bar_weather_icon_5.png differ
diff --git a/procentric/application/images/weather/top_bar_weather_icon_6.png b/procentric/application/images/weather/top_bar_weather_icon_6.png
new file mode 100755
index 0000000..6a985d7
Binary files /dev/null and b/procentric/application/images/weather/top_bar_weather_icon_6.png differ
diff --git a/procentric/application/images/weather/top_bar_weather_icon_7.png b/procentric/application/images/weather/top_bar_weather_icon_7.png
new file mode 100755
index 0000000..0c0547c
Binary files /dev/null and b/procentric/application/images/weather/top_bar_weather_icon_7.png differ
diff --git a/procentric/application/images/weather/top_bar_weather_icon_8.png b/procentric/application/images/weather/top_bar_weather_icon_8.png
new file mode 100755
index 0000000..cf414dc
Binary files /dev/null and b/procentric/application/images/weather/top_bar_weather_icon_8.png differ
diff --git a/procentric/application/images/weather/top_bar_weather_icon_9.png b/procentric/application/images/weather/top_bar_weather_icon_9.png
new file mode 100755
index 0000000..60c223d
Binary files /dev/null and b/procentric/application/images/weather/top_bar_weather_icon_9.png differ
diff --git a/procentric/application/images/weather/weather_icon_0.png b/procentric/application/images/weather/weather_icon_0.png
new file mode 100755
index 0000000..6358ebc
Binary files /dev/null and b/procentric/application/images/weather/weather_icon_0.png differ
diff --git a/procentric/application/images/weather/weather_icon_1.png b/procentric/application/images/weather/weather_icon_1.png
new file mode 100755
index 0000000..91aff19
Binary files /dev/null and b/procentric/application/images/weather/weather_icon_1.png differ
diff --git a/procentric/application/images/weather/weather_icon_10.png b/procentric/application/images/weather/weather_icon_10.png
new file mode 100755
index 0000000..67c5c0e
Binary files /dev/null and b/procentric/application/images/weather/weather_icon_10.png differ
diff --git a/procentric/application/images/weather/weather_icon_11.png b/procentric/application/images/weather/weather_icon_11.png
new file mode 100755
index 0000000..dc36ec3
Binary files /dev/null and b/procentric/application/images/weather/weather_icon_11.png differ
diff --git a/procentric/application/images/weather/weather_icon_12.png b/procentric/application/images/weather/weather_icon_12.png
new file mode 100755
index 0000000..8dfbfe2
Binary files /dev/null and b/procentric/application/images/weather/weather_icon_12.png differ
diff --git a/procentric/application/images/weather/weather_icon_13.png b/procentric/application/images/weather/weather_icon_13.png
new file mode 100755
index 0000000..2194a0f
Binary files /dev/null and b/procentric/application/images/weather/weather_icon_13.png differ
diff --git a/procentric/application/images/weather/weather_icon_14.png b/procentric/application/images/weather/weather_icon_14.png
new file mode 100755
index 0000000..f96becf
Binary files /dev/null and b/procentric/application/images/weather/weather_icon_14.png differ
diff --git a/procentric/application/images/weather/weather_icon_15.png b/procentric/application/images/weather/weather_icon_15.png
new file mode 100755
index 0000000..bded7c6
Binary files /dev/null and b/procentric/application/images/weather/weather_icon_15.png differ
diff --git a/procentric/application/images/weather/weather_icon_16.png b/procentric/application/images/weather/weather_icon_16.png
new file mode 100755
index 0000000..957904c
Binary files /dev/null and b/procentric/application/images/weather/weather_icon_16.png differ
diff --git a/procentric/application/images/weather/weather_icon_17.png b/procentric/application/images/weather/weather_icon_17.png
new file mode 100755
index 0000000..46dc067
Binary files /dev/null and b/procentric/application/images/weather/weather_icon_17.png differ
diff --git a/procentric/application/images/weather/weather_icon_18.png b/procentric/application/images/weather/weather_icon_18.png
new file mode 100755
index 0000000..22f8d5f
Binary files /dev/null and b/procentric/application/images/weather/weather_icon_18.png differ
diff --git a/procentric/application/images/weather/weather_icon_19.png b/procentric/application/images/weather/weather_icon_19.png
new file mode 100755
index 0000000..14d14e3
Binary files /dev/null and b/procentric/application/images/weather/weather_icon_19.png differ
diff --git a/procentric/application/images/weather/weather_icon_2.png b/procentric/application/images/weather/weather_icon_2.png
new file mode 100755
index 0000000..dafa95a
Binary files /dev/null and b/procentric/application/images/weather/weather_icon_2.png differ
diff --git a/procentric/application/images/weather/weather_icon_20.png b/procentric/application/images/weather/weather_icon_20.png
new file mode 100755
index 0000000..fcf3f92
Binary files /dev/null and b/procentric/application/images/weather/weather_icon_20.png differ
diff --git a/procentric/application/images/weather/weather_icon_21.png b/procentric/application/images/weather/weather_icon_21.png
new file mode 100755
index 0000000..092008a
Binary files /dev/null and b/procentric/application/images/weather/weather_icon_21.png differ
diff --git a/procentric/application/images/weather/weather_icon_22.png b/procentric/application/images/weather/weather_icon_22.png
new file mode 100755
index 0000000..29b19c6
Binary files /dev/null and b/procentric/application/images/weather/weather_icon_22.png differ
diff --git a/procentric/application/images/weather/weather_icon_23.png b/procentric/application/images/weather/weather_icon_23.png
new file mode 100755
index 0000000..ccd3735
Binary files /dev/null and b/procentric/application/images/weather/weather_icon_23.png differ
diff --git a/procentric/application/images/weather/weather_icon_24.png b/procentric/application/images/weather/weather_icon_24.png
new file mode 100755
index 0000000..ccd3735
Binary files /dev/null and b/procentric/application/images/weather/weather_icon_24.png differ
diff --git a/procentric/application/images/weather/weather_icon_25.png b/procentric/application/images/weather/weather_icon_25.png
new file mode 100755
index 0000000..e14ac92
Binary files /dev/null and b/procentric/application/images/weather/weather_icon_25.png differ
diff --git a/procentric/application/images/weather/weather_icon_26.png b/procentric/application/images/weather/weather_icon_26.png
new file mode 100755
index 0000000..1021b74
Binary files /dev/null and b/procentric/application/images/weather/weather_icon_26.png differ
diff --git a/procentric/application/images/weather/weather_icon_27.png b/procentric/application/images/weather/weather_icon_27.png
new file mode 100755
index 0000000..e28017b
Binary files /dev/null and b/procentric/application/images/weather/weather_icon_27.png differ
diff --git a/procentric/application/images/weather/weather_icon_28.png b/procentric/application/images/weather/weather_icon_28.png
new file mode 100755
index 0000000..ff57adc
Binary files /dev/null and b/procentric/application/images/weather/weather_icon_28.png differ
diff --git a/procentric/application/images/weather/weather_icon_29.png b/procentric/application/images/weather/weather_icon_29.png
new file mode 100755
index 0000000..b41999b
Binary files /dev/null and b/procentric/application/images/weather/weather_icon_29.png differ
diff --git a/procentric/application/images/weather/weather_icon_3.png b/procentric/application/images/weather/weather_icon_3.png
new file mode 100755
index 0000000..f559b76
Binary files /dev/null and b/procentric/application/images/weather/weather_icon_3.png differ
diff --git a/procentric/application/images/weather/weather_icon_30.png b/procentric/application/images/weather/weather_icon_30.png
new file mode 100755
index 0000000..c059f92
Binary files /dev/null and b/procentric/application/images/weather/weather_icon_30.png differ
diff --git a/procentric/application/images/weather/weather_icon_31.png b/procentric/application/images/weather/weather_icon_31.png
new file mode 100755
index 0000000..80df177
Binary files /dev/null and b/procentric/application/images/weather/weather_icon_31.png differ
diff --git a/procentric/application/images/weather/weather_icon_32.png b/procentric/application/images/weather/weather_icon_32.png
new file mode 100755
index 0000000..a3a1c9b
Binary files /dev/null and b/procentric/application/images/weather/weather_icon_32.png differ
diff --git a/procentric/application/images/weather/weather_icon_33.png b/procentric/application/images/weather/weather_icon_33.png
new file mode 100755
index 0000000..80df177
Binary files /dev/null and b/procentric/application/images/weather/weather_icon_33.png differ
diff --git a/procentric/application/images/weather/weather_icon_34.png b/procentric/application/images/weather/weather_icon_34.png
new file mode 100755
index 0000000..a3a1c9b
Binary files /dev/null and b/procentric/application/images/weather/weather_icon_34.png differ
diff --git a/procentric/application/images/weather/weather_icon_35.png b/procentric/application/images/weather/weather_icon_35.png
new file mode 100755
index 0000000..8eb4a89
Binary files /dev/null and b/procentric/application/images/weather/weather_icon_35.png differ
diff --git a/procentric/application/images/weather/weather_icon_36.png b/procentric/application/images/weather/weather_icon_36.png
new file mode 100755
index 0000000..94c9590
Binary files /dev/null and b/procentric/application/images/weather/weather_icon_36.png differ
diff --git a/procentric/application/images/weather/weather_icon_37.png b/procentric/application/images/weather/weather_icon_37.png
new file mode 100755
index 0000000..a47a1ac
Binary files /dev/null and b/procentric/application/images/weather/weather_icon_37.png differ
diff --git a/procentric/application/images/weather/weather_icon_38.png b/procentric/application/images/weather/weather_icon_38.png
new file mode 100755
index 0000000..06cb09c
Binary files /dev/null and b/procentric/application/images/weather/weather_icon_38.png differ
diff --git a/procentric/application/images/weather/weather_icon_39.png b/procentric/application/images/weather/weather_icon_39.png
new file mode 100755
index 0000000..dc36ec3
Binary files /dev/null and b/procentric/application/images/weather/weather_icon_39.png differ
diff --git a/procentric/application/images/weather/weather_icon_4.png b/procentric/application/images/weather/weather_icon_4.png
new file mode 100755
index 0000000..9281f4b
Binary files /dev/null and b/procentric/application/images/weather/weather_icon_4.png differ
diff --git a/procentric/application/images/weather/weather_icon_40.png b/procentric/application/images/weather/weather_icon_40.png
new file mode 100755
index 0000000..8dfbfe2
Binary files /dev/null and b/procentric/application/images/weather/weather_icon_40.png differ
diff --git a/procentric/application/images/weather/weather_icon_41.png b/procentric/application/images/weather/weather_icon_41.png
new file mode 100755
index 0000000..f96becf
Binary files /dev/null and b/procentric/application/images/weather/weather_icon_41.png differ
diff --git a/procentric/application/images/weather/weather_icon_42.png b/procentric/application/images/weather/weather_icon_42.png
new file mode 100755
index 0000000..99a61c4
Binary files /dev/null and b/procentric/application/images/weather/weather_icon_42.png differ
diff --git a/procentric/application/images/weather/weather_icon_43.png b/procentric/application/images/weather/weather_icon_43.png
new file mode 100755
index 0000000..d12707b
Binary files /dev/null and b/procentric/application/images/weather/weather_icon_43.png differ
diff --git a/procentric/application/images/weather/weather_icon_44.png b/procentric/application/images/weather/weather_icon_44.png
new file mode 100755
index 0000000..03559f7
Binary files /dev/null and b/procentric/application/images/weather/weather_icon_44.png differ
diff --git a/procentric/application/images/weather/weather_icon_45.png b/procentric/application/images/weather/weather_icon_45.png
new file mode 100755
index 0000000..dc36ec3
Binary files /dev/null and b/procentric/application/images/weather/weather_icon_45.png differ
diff --git a/procentric/application/images/weather/weather_icon_46.png b/procentric/application/images/weather/weather_icon_46.png
new file mode 100755
index 0000000..99a61c4
Binary files /dev/null and b/procentric/application/images/weather/weather_icon_46.png differ
diff --git a/procentric/application/images/weather/weather_icon_47.png b/procentric/application/images/weather/weather_icon_47.png
new file mode 100755
index 0000000..06cb09c
Binary files /dev/null and b/procentric/application/images/weather/weather_icon_47.png differ
diff --git a/procentric/application/images/weather/weather_icon_5.png b/procentric/application/images/weather/weather_icon_5.png
new file mode 100755
index 0000000..99a61c4
Binary files /dev/null and b/procentric/application/images/weather/weather_icon_5.png differ
diff --git a/procentric/application/images/weather/weather_icon_6.png b/procentric/application/images/weather/weather_icon_6.png
new file mode 100755
index 0000000..68260d0
Binary files /dev/null and b/procentric/application/images/weather/weather_icon_6.png differ
diff --git a/procentric/application/images/weather/weather_icon_7.png b/procentric/application/images/weather/weather_icon_7.png
new file mode 100755
index 0000000..de433f3
Binary files /dev/null and b/procentric/application/images/weather/weather_icon_7.png differ
diff --git a/procentric/application/images/weather/weather_icon_8.png b/procentric/application/images/weather/weather_icon_8.png
new file mode 100755
index 0000000..1652aac
Binary files /dev/null and b/procentric/application/images/weather/weather_icon_8.png differ
diff --git a/procentric/application/images/weather/weather_icon_9.png b/procentric/application/images/weather/weather_icon_9.png
new file mode 100755
index 0000000..668343a
Binary files /dev/null and b/procentric/application/images/weather/weather_icon_9.png differ
diff --git a/procentric/application/index.html b/procentric/application/index.html
new file mode 100755
index 0000000..1c8611f
--- /dev/null
+++ b/procentric/application/index.html
@@ -0,0 +1,81 @@
+
+
+
+
+
+
+
+
+ CENTIRM LG-PROCENTRIC HOTEL SERVICE
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/procentric/application/lib/acmeticker.js b/procentric/application/lib/acmeticker.js
new file mode 100755
index 0000000..141315f
--- /dev/null
+++ b/procentric/application/lib/acmeticker.js
@@ -0,0 +1,373 @@
+(function($) {
+ 'use strict';
+ $.fn.AcmeTicker = function(options) {
+ /*Merge options and default options*/
+ let opts = $.extend({}, $.fn.AcmeTicker.defaults, options);
+
+ /*Functions Scope*/
+ let thisTicker = $(this),
+ intervalID, timeoutID, isPause = false;
+
+ /*Always wrap, used in many place*/
+ thisTicker.wrap("");
+
+ /*Wrap is always relative*/
+ thisTicker.parent().css({
+ position: 'relative'
+ })
+ /*Hide expect first*/
+ thisTicker.children("li").not(":first").hide();
+
+ /*Lets init*/
+ init();
+
+ function init() {
+ switch (opts.type) {
+ case 'vertical':
+ case 'horizontal':
+ vertiZontal()
+ break;
+
+ case 'marquee':
+ marQuee()
+ break;
+
+ case 'typewriter':
+ typeWriter()
+ break;
+
+ default:
+ break
+ }
+ }
+
+ /*Vertical - horizontal
+ * **Do not change code lines*/
+ function vertiZontal(prevNext = false) {
+ let speed = opts.speed,
+ autoplay = opts.autoplay,
+ direction = opts.direction;
+
+ if (prevNext) {
+ speed = 0;
+ autoplay = 0;
+ clearInterval(intervalID);
+ intervalID = false;
+ }
+
+ function play() {
+ if (isPause) {
+ clearInterval(intervalID);
+ intervalID = false;
+ return false;
+ }
+ let dChild,
+ eqType,
+ mType,
+ mVal;
+
+ dChild = thisTicker.find('li:first');
+ if (direction === 'up' || direction === 'right') {
+ eqType = '-=';
+ } else {
+ eqType = '+=';
+ }
+ if (opts.type === 'horizontal') {
+ mType = 'left';
+ mVal = dChild.outerWidth(true);
+ } else {
+ mType = 'margin-top';
+ mVal = dChild.outerHeight(true);
+ }
+ if (prevNext === 'prev') {
+ thisTicker.find('li:last').detach().prependTo(thisTicker);
+ } else {
+ dChild.detach().appendTo(thisTicker);
+ }
+
+ thisTicker.find('li').css({
+ opacity: '0',
+ display: 'none'
+ });
+ thisTicker.find('li:first').css({
+ opacity: '1',
+ position: 'absolute',
+ display: 'block',
+ [mType]: eqType + mVal + 'px',
+ });
+ thisTicker.find('li:first').animate({
+ [mType]: '0px'
+ },
+ speed,
+ function() {
+ clearInterval(intervalID);
+ intervalID = false;
+ vertiZontal();
+ });
+ }
+ if (intervalID) {
+ return false
+ }
+ intervalID = setInterval(play, autoplay);
+ }
+
+ /*Type-Writer
+ * **Do not change code lines*/
+ function typeWriter(prevNext = false) {
+ if (isPause) {
+ return false;
+ }
+ if (prevNext) {
+ clearInterval(intervalID);
+ intervalID = false;
+
+ clearTimeout(timeoutID);
+ timeoutID = false;
+
+ if (prevNext === 'prev') {
+ thisTicker.find('li:last').detach().prependTo(thisTicker);
+ } else {
+ thisTicker.find('li:first').detach().appendTo(thisTicker);
+ }
+ }
+
+ let speed = opts.speed,
+ autoplay = opts.autoplay,
+ typeEl = thisTicker.find('li:first'),
+ wrapEl = typeEl.children(),
+ count = 0;
+
+ if (typeEl.attr('data-text')) {
+ wrapEl.text(typeEl.attr('data-text'))
+ }
+
+ let allText = typeEl.text();
+
+ thisTicker.find('li').css({
+ opacity: '0',
+ display: 'none'
+ });
+
+ function tNext() {
+ thisTicker.find('li:first').detach().appendTo(thisTicker);
+
+ clearTimeout(timeoutID);
+ timeoutID = false;
+
+ typeWriter();
+ }
+
+ function type() {
+ count++;
+ let typeText = allText.substring(0, count);
+ if (!typeEl.attr('data-text')) {
+ typeEl.attr('data-text', allText);
+ }
+
+ if (count <= allText.length) {
+ wrapEl.text(typeText);
+ typeEl.css({
+ opacity: '1',
+ display: 'block',
+ });
+ } else {
+ clearInterval(intervalID);
+ intervalID = false;
+ timeoutID = setTimeout(tNext, autoplay);
+ }
+ }
+ if (!intervalID) {
+ intervalID = setInterval(type, speed);
+ }
+ }
+
+ /*marQuee
+ * **Do not change code lines*/
+ function marQuee() {
+ /*Marquee Special*/
+ let speed = opts.speed,
+ direction = opts.direction,
+ wrapWidth,
+ dir = 'left',
+ totalTravel,
+ defTiming,
+ listWidth = 0,
+ mPause = false;
+
+ mInit();
+
+ function mInit() {
+ thisTicker.css({
+ position: 'absolute'
+ })
+ thisTicker.find('li').css({
+ display: 'inline-block',
+ marginRight: '10px',
+ });
+ let tickerList = thisTicker.find("li");
+ wrapWidth = thisTicker.parent().outerWidth(true);
+
+ if (direction === 'right') {
+ dir = 'right'
+ }
+
+ /*Calculating ticker width*/
+ thisTicker.width(10000); /*temporary width to prevent inline elements wrapping to initial width of ticker*/
+ tickerList.each(function() {
+ listWidth += $(this).outerWidth(true) + 5; /*+5 for some missing px*/
+ });
+ thisTicker.width(listWidth);
+
+ totalTravel = listWidth + wrapWidth;
+ defTiming = totalTravel / speed;
+
+ marQueeIt(listWidth, listWidth / speed);
+ }
+
+ function marQueeIt(lPos, lSpeed) {
+ thisTicker.animate({
+ [dir]: '-=' + lPos
+ },
+ lSpeed,
+ "linear",
+ function() {
+ thisTicker.css({
+ [dir]: wrapWidth
+ });
+ marQueeIt(totalTravel, defTiming);
+ }
+ );
+ }
+
+ function mRestart() {
+ let offset = thisTicker.offset(),
+ rOffset = direction === 'right' ? (listWidth - offset.left) : offset.left,
+ remainingSpace = rOffset + listWidth,
+ remainingTime = remainingSpace / speed;
+
+ marQueeIt(remainingSpace, remainingTime);
+ }
+
+ function mToggle() {
+ console.log('mToggle')
+
+ mPause = !mPause;
+ $(document).trigger('acmeTickerToggle', thisTicker, mPause)
+ if (mPause) {
+ thisTicker.stop();
+ } else {
+ mRestart();
+ }
+ }
+
+ opts.controls.toggle && opts.controls.toggle.on('click', function(e) {
+ mToggle();
+ });
+ if (opts.pauseOnHover) {
+ thisTicker.on('mouseenter', function() {
+ thisTicker.stop();
+ }).on('mouseleave', function() {
+ mRestart();
+ });
+ }
+ if (opts.pauseOnFocus) {
+ thisTicker.on('focusin', function() {
+ thisTicker.stop();
+ }).on('focusout', function() {
+ mRestart();
+ });
+ }
+ }
+ /*marQuee End*/
+
+ /*Actions/Controls*/
+ if (opts.type !== 'marquee') {
+ opts.controls.prev && opts.controls.prev.on('click', function(e) {
+ e.preventDefault();
+ switch (opts.type) {
+ case 'typewriter':
+ typeWriter('prev')
+ break;
+
+ default:
+ vertiZontal('prev')
+ break
+ }
+ });
+ opts.controls.next && opts.controls.next.on('click', function(e) {
+ e.preventDefault();
+ switch (opts.type) {
+ case 'typewriter':
+ typeWriter('next')
+ break;
+
+ default:
+ vertiZontal('next')
+ break
+ }
+ });
+
+ function restart() {
+ if (!isPause) {
+ init();
+ }
+ }
+ opts.controls.toggle && opts.controls.toggle.on('click', function(e) {
+ e.preventDefault();
+ isPause = !isPause;
+ $(document).trigger('acmeTickerToggle', thisTicker, isPause)
+ restart();
+ });
+ if (opts.pauseOnHover) {
+ thisTicker.on('mouseenter', function() {
+ isPause = true;
+ restart();
+ }).on('mouseleave', function() {
+ isPause = false;
+ restart();
+ });
+ }
+ if (opts.pauseOnFocus) {
+ thisTicker.on('focusin', function() {
+ isPause = true;
+ restart();
+ }).on('focusout', function() {
+ isPause = false;
+ restart();
+ });
+ }
+ }
+ };
+
+ // plugin defaults - added as a property on our plugin function
+ $.fn.AcmeTicker.defaults = {
+ /*Note: Marquee only take speed not autoplay*/
+ type: 'horizontal',
+ /*vertical/horizontal/marquee/typewriter*/
+ autoplay: 2000,
+ /*true/false/number*/
+ /*For vertical/horizontal 4000*/
+ /*For typewriter 2000*/
+ speed: 50,
+ /*true/false/number*/
+ /*For vertical/horizontal 600*/
+ /*For marquee 0.05*/
+ /*For typewriter 50*/
+ direction: 'up',
+ /*up/down/left/right*/
+ /*For vertical up/down*/
+ /*For horizontal/marquee right/left*/
+ /*For typewriter direction doesnot work*/
+ pauseOnFocus: true,
+ pauseOnHover: true,
+ controls: {
+ prev: '',
+ /*Can be used for vertical/horizontal/typewriter*/
+ /*not work for marquee*/
+ next: '',
+ /*Can be used for vertical/horizontal/typewriter*/
+ /*not work for marquee*/
+ toggle: '' /*Can be used for vertical/horizontal/marquee/typewriter*/
+ }
+ };
+})(jQuery);
\ No newline at end of file
diff --git a/procentric/application/lib/acmeticker.min.js b/procentric/application/lib/acmeticker.min.js
new file mode 100755
index 0000000..5917e6f
--- /dev/null
+++ b/procentric/application/lib/acmeticker.min.js
@@ -0,0 +1,2 @@
+!function(t){"use strict";t.fn.AcmeTicker=function(e){let n,i,o=t.extend({},t.fn.AcmeTicker.defaults,e),c=t(this),r=!1;function a(){switch(o.type){case"vertical":case"horizontal":l();break;case"marquee":!function(){let e,n,i,r=o.speed,a=o.direction,l="left",s=0,u=!1;function f(t,o){c.animate({[l]:"-="+t},o,"linear",function(){c.css({[l]:e}),f(n,i)})}function p(){let t=c.offset(),e="right"===a?s-t.left:t.left,n=e+s,i=n/r;f(n,i)}(function(){c.css({position:"absolute"}),c.find("li").css({display:"inline-block",marginRight:"10px"});let o=c.find("li");e=c.parent().outerWidth(!0),"right"===a&&(l="right"),c.width(1e4),o.each(function(){s+=t(this).outerWidth(!0)+5}),c.width(s),i=(n=s+e)/r,f(s,s/r)})(),o.controls.toggle&&o.controls.toggle.on("click",function(e){console.log("mToggle"),u=!u,t(document).trigger("acmeTickerToggle",c,u),u?c.stop():p()}),o.pauseOnHover&&c.on("mouseenter",function(){c.stop()}).on("mouseleave",function(){p()});o.pauseOnFocus&&c.on("focusin",function(){c.stop()}).on("focusout",function(){p()})}();break;case"typewriter":s()}}function l(t=!1){let e=o.speed,i=o.autoplay,a=o.direction;if(t&&(e=0,i=0,clearInterval(n),n=!1),n)return!1;n=setInterval(function(){if(r)return clearInterval(n),n=!1,!1;let i,s,u,f;i=c.find("li:first"),s="up"===a||"right"===a?"-=":"+=","horizontal"===o.type?(u="left",f=i.outerWidth(!0)):(u="margin-top",f=i.outerHeight(!0)),"prev"===t?c.find("li:last").detach().prependTo(c):i.detach().appendTo(c),c.find("li").css({opacity:"0",display:"none"}),c.find("li:first").css({opacity:"1",position:"absolute",display:"block",[u]:s+f+"px"}),c.find("li:first").animate({[u]:"0px"},e,function(){clearInterval(n),n=!1,l()})},i)}function s(t=!1){if(r)return!1;t&&(clearInterval(n),n=!1,clearTimeout(i),i=!1,"prev"===t?c.find("li:last").detach().prependTo(c):c.find("li:first").detach().appendTo(c));let e=o.speed,a=o.autoplay,l=c.find("li:first"),u=l.children(),f=0;l.attr("data-text")&&u.text(l.attr("data-text"));let p=l.text();function d(){c.find("li:first").detach().appendTo(c),clearTimeout(i),i=!1,s()}c.find("li").css({opacity:"0",display:"none"}),n||(n=setInterval(function(){f++;let t=p.substring(0,f);l.attr("data-text")||l.attr("data-text",p),f<=p.length?(u.text(t),l.css({opacity:"1",display:"block"})):(clearInterval(n),n=!1,i=setTimeout(d,a))},e))}if(c.wrap(""),c.parent().css({position:"relative"}),c.children("li").not(":first").hide(),a(),"marquee"!==o.type){function u(){r||a()}o.controls.prev&&o.controls.prev.on("click",function(t){switch(t.preventDefault(),o.type){case"typewriter":s("prev");break;default:l("prev")}}),o.controls.next&&o.controls.next.on("click",function(t){switch(t.preventDefault(),o.type){case"typewriter":s("next");break;default:l("next")}}),o.controls.toggle&&o.controls.toggle.on("click",function(e){e.preventDefault(),r=!r,t(document).trigger("acmeTickerToggle",c,r),u()}),o.pauseOnHover&&c.on("mouseenter",function(){r=!0,u()}).on("mouseleave",function(){r=!1,u()}),o.pauseOnFocus&&c.on("focusin",function(){r=!0,u()}).on("focusout",function(){r=!1,u()})}},t.fn.AcmeTicker.defaults={type:"horizontal",autoplay:2e3,speed:50,direction:"up",pauseOnFocus:!0,pauseOnHover:!0,controls:{prev:"",next:"",toggle:""}}}(jQuery);
+//# sourceMappingURL=acmeticker.min.js.map
\ No newline at end of file
diff --git a/procentric/application/lib/hcap.debug.js b/procentric/application/lib/hcap.debug.js
new file mode 100755
index 0000000..3ab9d74
--- /dev/null
+++ b/procentric/application/lib/hcap.debug.js
@@ -0,0 +1,530 @@
+/*!
+ * ============================================================================
+ * Creative Innovation Center, LG ELECTRONICS INC., SEOUL, KOREA
+ * Copyright(c) 2018 by LG Electronics Inc.
+ *
+ * Release Version : 1.24.2.5850
+ * ============================================================================
+ */
+var extHcapSecure;
+var extRegisterHcapCloseHandler;
+var extDisableHcapConsoleLog;
+var extWebWorker;
+var hcap;
+if (hcap === undefined) {
+ (function() { hcap = { API_VERSION: "1.24.2.5850" }; var g = [],
+ e = 0,
+ i = [{ command_id: "0", param_text: '{"command_id" : "0", "command" : "notify_sdk_version", "hcap_js_extension_version" : "1.24.2.5850"}' }],
+ k = null,
+ o = false,
+ d = false,
+ n = false,
+ c = null,
+ f = null,
+ l = null,
+ b = false,
+ m = null,
+ a = null;
+
+ function j(r) { if (extDisableHcapConsoleLog !== true) { var t; if (r.length > 1024) { t = r.substring(0, 1024) } else { t = r } if (extWebWorker !== true) { console.log(t) } } } if (extDisableHcapConsoleLog === true) { if (extWebWorker !== true) { console.log("hcap console log is disabled") } } else { if (extWebWorker !== true) { console.log("hcap console log is enabled") } }
+ j("check external value : extDisableHcapConsoleLog = " + extDisableHcapConsoleLog + ", extHcapSecure = " + extHcapSecure + ", extRegisterHcapCloseHandler = " + extRegisterHcapCloseHandler);
+
+ function p() { var r = navigator.userAgent,
+ t = r.match(/Windows/),
+ s = r.match(/Macintosh/),
+ u = r.match(/Mac OS X/);
+ j("UA = '" + r + "'"); if (t || s || u) { j("HCAP websocket off"); return true } return false }
+ b = p();
+
+ function h(r, x, s, y) { var v = "",
+ t = "",
+ u = "";
+ u = x[r]; try { v = s[u];
+ t = typeof v } catch (w) { v = "";
+ t = "unknown" } if (t === "function") { v = "{/*function*/}" } else { if (t === "object") { v = m("", v) } else { if (t === "string") { v = '"' + v + '"' } } }
+ y += '"' + u + '" : ' + v; if (r < x.length - 1) { y += ", " } return y }
+ m = function(u, s) { var t = 0,
+ r = "",
+ v = [],
+ w = ""; for (r in s) { if (s.hasOwnProperty(r)) { v.push(r) } }
+ v.sort(); for (t = 0; t < v.length; t += 1) { w = h(t, v, s, w) } return u + "{" + w + "}" };
+
+ function q(v, u) { if (extWebWorker !== true) { var t = "",
+ s = v,
+ r = document.createEvent("HTMLEvents");
+ j(m("event received, ", u));
+ r.initEvent(s, true, false); for (t in u) { if (u.hasOwnProperty(t)) { r[t] = u[t] } }
+ document.dispatchEvent(r) } }
+ c = function() { if (d) { j("websocket : connection is in progress"); return }
+ d = true; if (extHcapSecure !== true) { j("default hcap connection");
+ k = new WebSocket("ws://127.0.0.1:8053/hcap_command") } else { j("secure hcap connection");
+ k = new WebSocket("wss://localhost:8054/hcap_command") }
+ k.onopen = function() { j("websocket : onopen");
+ d = false;
+ o = true;
+ setTimeout(f, 5) };
+ k.onmessage = function(r) { var w = JSON.parse(r.data),
+ s = w.command_id,
+ v = w.command,
+ u = w.result; if (s === "event") { if (v === "debug_event_received") { if (w.enable_log) { if (extWebWorker !== true) { console.log("hcap console log is enabled") } } else { if (extWebWorker !== true) { console.log("hcap console log is disabled") } }
+ extDisableHcapConsoleLog = !w.enable_log } else { q(v, w) } } else { if (i.length > 0 && i[0].command_id === s) { j(m("command_id = " + s + " received, ", w)); if (u) { if (i[0].onSuccess) { try { i[0].onSuccess(w) } catch (t) { j(m("exception : onSuccess : " + t)) } } } else { if (i[0].onFailure) { try { i[0].onFailure(w) } catch (t) { j(m("exception : onFailure : " + t)) } } }
+ i.splice(0, 1);
+ n = false;
+ f() } else { j(m("invalid response from server ", w));
+ n = false;
+ f() } } };
+ k.onclose = function() { j("websocket : onclose");
+ d = false;
+ o = false;
+ n = false;
+ setTimeout(f, 50) }; if (extRegisterHcapCloseHandler === "onbeforeunload") { window.onbeforeunload = function() { j("close hcap websocket in onbeforeunload handler");
+ k.onclose = function() { return undefined };
+ k.close() } } else { if (extRegisterHcapCloseHandler === "onunload") { window.onunload = function() { j("close hcap websocket in onunload handler");
+ k.onclose = function() { return undefined };
+ k.close() } } } };
+ f = function() { if (n) { return }
+ n = true; if (o) { if (i.length > 0) { j(m("command_id = " + i[0].command_id + " sent, ", JSON.parse(i[0].param_text)));
+ k.send(i[0].param_text); return } } else { c() }
+ n = false };
+ l = function(u, t) { if (u === null || u === "" || u === undefined) { j('[ERROR] command should not null or empty string! command === null || command === "" || command === undefined'); return } if (Object.prototype.toString.call(t) === "[object Array]") { j("[ERROR] param should be Object type({})! param is Array. command = " + u); return } if (t === null || t === undefined) { j("[ERROR] param should be Object type({})! param === null || param === undefined. command = " + u); return } if (b) { if (t.onFailure) { t.onFailure({ errorMessage: "HCAP WebSocket is not available in this browser" }) } return } if (e > 1024) { e = 0 } else { e += 1 } var r = e.toString(),
+ s = "";
+ t.command_id = r;
+ t.command = u;
+ s = JSON.stringify(t, null);
+ i[i.length] = { command_id: r, param_text: s, onSuccess: t.onSuccess, onFailure: t.onFailure };
+ j(m("command_id = " + r + " added, ", i[i.length - 1]));
+ f() }; if (!b) { setTimeout(f, 200) }
+ hcap.preloadedApplication = {};
+ hcap.preloadedApplication.getPreloadedApplicationList = function(r) { l("get_preloaded_application_list", r) };
+ hcap.preloadedApplication.launchPreloadedApplication = function(r) { l("launch_preloaded_application", r) };
+ hcap.preloadedApplication.destroyPreloadedApplication = function(r) { l("destroy_preloaded_application", r) };
+ hcap.application = {};
+ hcap.application.getServiceXml = function(r) { l("get_service_xml", r) };
+ hcap.application.getDefaultServiceXml = function(r) { l("get_default_service_xml", r) };
+ hcap.application.getApplicationList = function(r) { l("get_application_list", r) };
+ hcap.application.launchApplication = function(r) { l("launch_application", r) };
+ hcap.application.destroyApplication = function(r) { l("destroy_application", r) };
+ hcap.application.RegisterSIApplicationList = function(r) { l("register_si_app_list", r) };
+ hcap.video = {};
+ hcap.video.getVideoSize = function(r) { l("get_video_size", r) };
+ hcap.video.setVideoSize = function(r) { l("set_video_size", r) };
+ hcap.video.getOsdTransparencyLevel = function(r) { l("get_osd_transparency_level", r) };
+ hcap.video.setOsdTransparencyLevel = function(r) { l("set_osd_transparency_level", r) };
+ hcap.video.isVideoMute = function(r) { l("get_video_mute", r) };
+ hcap.video.setVideoMute = function(r) { l("set_video_mute", r) };
+ hcap.volume = {};
+ hcap.volume.getVolumeLevel = function(r) { l("get_volume_level", r) };
+ hcap.volume.setVolumeLevel = function(r) { l("set_volume_level", r) };
+ hcap.volume.getExternalSpeakerVolumeLevel = function(r) { l("get_external_speaker_volume_level", r) };
+ hcap.volume.setExternalSpeakerVolumeLevel = function(r) { l("set_external_speaker_volume_level", r) };
+ hcap.volume.getHeadphoneVolumeLevel = function(r) { l("get_headphone_volume_level", r) };
+ hcap.volume.setHeadphoneVolumeLevel = function(r) { l("set_headphone_volume_level", r) };
+ hcap.volume.setHealthcareHeadphoneMode = function(r) { l("set_healthcare_headphone_mode", r) };
+ hcap.volume.getHealthcareHeadphoneMode = function(r) { l("get_healthcare_headphone_mode", r) };
+ hcap.channel = {};
+ hcap.channel.NO_STREAM_PID = 8191;
+ hcap.channel.ChannelType = { UNKNOWN: 0, RF: 1, IP: 2, RF_DATA: 3, IP_DATA: 4 };
+ hcap.channel.Polarization = { UNKNOWN: 0, VERTICAL: 1, HORIZONTAL: 2, LEFT_HAND_CIRCULAR: 3, RIGHT_HAND_CIRCULAR: 4 };
+ hcap.channel.RfBroadcastType = { UNKNOWN: 0, TERRESTRIAL: 16, TERRESTRIAL_2: 17, SATELLITE: 32, SATELLITE_2: 33, SATELLITE_CS1: 34, SATELLITE_CS2: 35, SATELLITE_S3_BS: 36, SATELLITE_S3_CS: 37, CABLE: 48, CABLE_STD: 49, CABLE_HRC: 50, CABLE_IRC: 51, ANALOG_PAL_BG: 64, ANALOG_PAL_DK: 65, ANALOG_PAL_I: 66, ANALOG_PAL_M: 67, ANALOG_PAL_N: 68, ANALOG_SECAM_BG: 69, ANALOG_SECAM_DK: 70, ANALOG_SECAM_L: 71, ANALOG_NTSC: 72, TERRESTRIAL_ATSC3: 80, CABLE_ATSC3: 81 };
+ hcap.channel.IpBroadcastType = { UNKNOWN: 0, UDP: 16, RTP: 32 };
+ hcap.channel.VideoStreamType = { MPEG1: 1, MPEG2: 2, MPEG4_VISUAL: 16, MPEG4_AVC_H264: 27, HEVC: 36, AVS: 66 };
+ hcap.channel.AudioStreamType = { MPEG1: 3, MPEG2: 4, MPEG2_AAC: 15, MPEG4_HEAAC: 17, AC3: 129, EAC3: 130, ANALOG_BG: 256, ANALOG_I: 257, ANALOG_DK: 258, ANALOG_L: 259, ANALOG_MN: 260, ANALOG_LP: 261, ANALOG_END: 262 };
+ hcap.channel.InbandDataServiceType = { UNKNOWN: 0, MHP: 1, MHEG: 2, HBBTV: 3, NONE: 4 };
+ hcap.channel.ChannelStatus = { UNKNOWN: 0, AUDIO_VIDEO_NOT_BLOCKED: 16, AV_DISPLAYED: 16, AUDIO_VIDEO_BLOCKED: 33, NO_SIGNAL: 33, AUDIO_ONLY_BLOCKED: 34, VIDEO_ONLY_BLOCKED: 35 };
+ hcap.channel.requestChangeCurrentChannel = function(r) { l("request_channel_change", r) };
+ hcap.channel.getCurrentChannel = function(r) { l("get_current_channel", r) };
+ hcap.channel.replayCurrentChannel = function(r) { l("replay_current_channel", r) };
+ hcap.channel.stopCurrentChannel = function(r) { l("stop_current_channel", r) };
+ hcap.channel.getDataChannel = function(r) { l("get_data_channel", r) };
+ hcap.channel.getChannelMap = function(r) { l("get_channel_map", r) };
+ hcap.channel.getStartChannel = function(r) { l("get_start_channel", r) };
+ hcap.channel.setStartChannel = function(r) { l("set_start_channel", r) };
+ hcap.channel.getCurrentChannelAudioLanguageList = function(r) { l("get_current_channel_audio_language_list", r) };
+ hcap.channel.getCurrentChannelAudioLanguageIndex = function(r) { l("get_current_channel_audio_language_index", r) };
+ hcap.channel.setCurrentChannelAudioLanguageIndex = function(r) { l("set_current_channel_audio_language_index", r) };
+ hcap.channel.getCurrentChannelSubtitleList = function(r) { l("get_current_channel_subtitle_language_list", r) };
+ hcap.channel.getCurrentChannelSubtitleIndex = function(r) { l("get_current_channel_subtitle_language_index", r) };
+ hcap.channel.setCurrentChannelSubtitleIndex = function(r) { l("set_current_channel_subtitle_language_index", r) };
+ hcap.channel.getProgramInfo = function(r) { l("get_program_info", r) };
+ hcap.channel.launchInbandDataService = function(r) { l("launch_inband_data_service", r) };
+ hcap.channel.getReadyInbandDataService = function(r) { l("get_ready_inband_data_service", r) };
+ hcap.channel.getChannelSignalStatus = function(r) { l("get_channel_signal_status", r) };
+ hcap.externalinput = {};
+ hcap.externalinput.ExternalInputType = { TV: 1, COMPOSITE: 2, SVIDEO: 3, COMPONENT: 4, RGB: 5, HDMI: 6, SCART: 7, USB: 8, OTHERS: 9 };
+ hcap.externalinput.getCurrentExternalInput = function(r) { l("get_external_input", r) };
+ hcap.externalinput.setCurrentExternalInput = function(r) { l("set_external_input", r) };
+ hcap.externalinput.isExternalInputConnected = function(r) { l("check_external_input_connected", r) };
+ hcap.externalinput.getExternalInputList = function(r) { l("get_external_input_list", r) };
+ hcap.carousel = {};
+ hcap.carousel.requestCacheCarouselData = function(r) { l("request_content", r) };
+ hcap.carousel.isCarouselDataCached = function(r) { l("is_content_loaded", r) };
+ hcap.carousel.clearCarouselDataCache = function(r) { l("clear_content_cache", r) };
+ hcap.mpi = {};
+ hcap.mpi.sendAndReceiveMpiData = function(r) { l("send_and_receive_mpi_data", r) };
+ hcap.mpi.sendMpiData = function(r) { l("send_mpi_data", r) };
+ hcap.power = {};
+ hcap.power.PowerMode = { WARM: 2, NORMAL: 1 };
+ hcap.power.getPowerMode = function(r) { l("get_power_mode", r) };
+ hcap.power.setPowerMode = function(r) { l("set_power_mode", r) };
+ hcap.power.isWarmUpdate = function(r) { l("is_power_warm_update", r) };
+ hcap.power.powerOff = function(r) { l("power_off", r) };
+ hcap.power.reboot = function(r) { l("reboot", r) };
+ hcap.time = {};
+ hcap.time.setLocalTime = function(r) { l("set_tv_localtime", r) };
+ hcap.time.getLocalTime = function(r) { l("get_tv_localtime", r) };
+ hcap.time.getPowerOffTimer = function(r) { l("get_power_off_timer_in_min", r) };
+ hcap.time.setPowerOffTimer = function(r) { l("set_power_off_timer_in_min", r) };
+ hcap.time.getPowerOnTime = function(r) { l("get_power_on_time", r) };
+ hcap.time.setPowerOnTime = function(r) { l("set_power_on_time", r) };
+ hcap.time.getAlarmInformation = function(r) { l("get_alarm_information", r) };
+ hcap.time.setAlarmInformation = function(r) { l("set_alarm_information", r) };
+ hcap.time.getCpuTime = function(r) { l("get_cpu_time", r) };
+ hcap.network = {};
+ hcap.network.getNumberOfNetworkDevices = function(r) { l("get_number_of_network_devices", r) };
+ hcap.network.getNetworkDevice = function(r) { l("get_network_device", r) };
+ hcap.network.setNetworkDevice = function(r) { l("set_network_device", r) };
+ hcap.network.ping = function(r) { l("ping", r) };
+ hcap.network.NetworkEventType = { UNKNOWN: 0, ETHERNET_PLUGGED: 1, ETHERNET_UNPLUGGED: 2, WIFI_DONGLE_PLUGGED: 3, WIFI_DONGLE_UNPLUGGED: 4, IP_CONFLICT: 5, IP_NOT_CONFLICT: 6, DHCP_SUCCESS: 7, DHCP_FAIL: 8, UNABLE_REACH_GATEWAY: 9, ABLE_REACH_GATEWAY: 10, UNABLE_REACH_DNS: 11, ABLE_REACH_DNS: 12, UNABLE_REACH_INTERNET: 13, ABLE_REACH_INTERNET: 14, WIFI_AP_SEARCH_COMPLETE: 15, WIFI_CONNECTED: 16, WIFI_CONNECT_FAIL: 17, WIFI_LINK_DROPPED: 18 };
+ hcap.network.NetworkMode = { UNKNOWN: 0, WIRE: 1, WIRELESS: 2, NOT_REACHABLE: 3 };
+ hcap.network.WirelessMode = { UNKNOWN: 0, INFRA: 1, ADHOC: 2 };
+ hcap.network.WifiSecurityType = { UNKNOWN: 0, OPEN: 1, WEP: 2, WPA_PSK_TKIP: 3, WPA_PSK_AES: 4, WPA2_PSK_TKIP: 5, WPA2_PSK_AES: 6, WPA12_PSK_AES_TKIPAES: 7 };
+ hcap.network.DhcpState = { UNKNOWN: 0, INIT: 1, SELECTING: 2, REQUESTING: 3, BOUND: 4, RENEWING: 5, REBINDING: 6, INIT_REBOOT: 7, REBOOTING: 8 };
+ hcap.network.getNetworkInformation = function(r) { l("get_network_information", r) };
+ hcap.network.getSoftAP = function(r) { l("get_soft_ap", r) };
+ hcap.network.setSoftAP = function(r) { l("set_soft_ap", r) };
+ hcap.network.getWifiDiagnostics = function(r) { l("get_wifi_diagnostics", r) };
+ hcap.network.asyncPing = function(r) { l("async_ping", r) };
+ hcap.network.setVlanIdMode = function(r) { l("set_vlan_id_mode", r) };
+ hcap.network.getVlanIdMode = function(r) { l("get_vlan_id_mode", r) };
+ hcap.network.getLanId = function(r) { l("get_lan_id", r) };
+ hcap.network.setLanId = function(r) { l("set_lan_id", r) };
+ hcap.network.getAuxLanId = function(r) { l("get_aux_lan_id", r) };
+ hcap.network.setAuxLanId = function(r) { l("set_aux_lan_id", r) };
+ hcap.network.getBlockedPortList = function(r) { l("get_blocked_port_list", r) };
+ hcap.network.setBlockedPortList = function(r) { l("set_blocked_port_list", r) };
+ hcap.mode = {};
+ hcap.mode.HCAP_MODE_0 = 257;
+ hcap.mode.HCAP_MODE_1 = 258;
+ hcap.mode.HCAP_MODE_2 = 259;
+ hcap.mode.HCAP_MODE_3 = 260;
+ hcap.mode.HCAP_MODE_4 = 261;
+ hcap.mode.getHcapMode = function(r) { l("get_mw_mode", r) };
+ hcap.mode.setHcapMode = function(r) { l("set_mw_mode", r) };
+ hcap.key = {};
+ hcap.key.Code = { NUM_0: 48, NUM_1: 49, NUM_2: 50, NUM_3: 51, NUM_4: 52, NUM_5: 53, NUM_6: 54, NUM_7: 55, NUM_8: 56, NUM_9: 57, CH_UP: 427, CH_DOWN: 428, GUIDE: 458, INFO: 457, LEFT: 37, UP: 38, RIGHT: 39, DOWN: 40, ENTER: 13, BACK: 461, EXIT: 1001, RED: 403, GREEN: 404, YELLOW: 405, BLUE: 406, STOP: 413, PLAY: 415, PAUSE: 19, REWIND: 412, FAST_FORWARD: 417, LAST_CH: 711, PORTAL: 602, ORDER: 623, MINUS: 704, POWER: 409, VOL_UP: 447, VOL_DOWN: 448, MUTE: 449, RECORD: 416, PAGE_UP: 33, PAGE_DOWN: 34, RF_BYPASS: 29, NEXT_DAY: 425, PREV_DAY: 424, APPS: 93, LINK: 606, FORWARD: 167, ZOOM: 251, SETTINGS: 611, NEXT_FAV_CH: 176, RES_1: 112, RES_2: 113, RES_3: 114, RES_4: 115, RES_5: 116, RES_6: 117, LOCK: 619, SKIP: 620, LIST: 1006, LIVE: 622, ON_DEMAND: 623, PINP_MOVE: 624, PINP_UP: 625, PINP_DOWN: 626, MENU: 18, AD: 700, ALARM: 701, AV_MODE: 31, SUBTITLE: 460, CC: 1008, DISC_POWER_OFF: 705, DISC_POWER_ON: 706, DVD: 707, EJECT: 414, ENERGY_SAVING: 709, FAV: 710, FLASHBK: 711, INPUT: 712, MARK: 713, NETCAST: 1000, PIP: 715, PIP_CH_DOWN: 716, PIP_CH_UP: 717, PIP_INPUT: 718, PIP_SWAP: 719, Q_MENU: 1002, Q_VIEW: 1007, RATIO: 1005, SAP: 723, SIMPLINK: 724, STB: 725, T_OPT: 1004, TEXT: 459, SLEEP_TIMER: 729, TV: 730, TV_RAD: 731, VCR: 732, POWER_LOWBATTERY: 733, SMART_HOME: 734, SCREEN_REMOTE: 735, POINTER: 736, LG_3D: 737, DATA: 738, ASSISTIVE_MENU: 739, THREE_DIGIT_INPUT: 740, LIVETV: 741, GOTOPREV: 742, GOTONEXT: 743, TER: 744, BS: 745, CS1: 746, CS2: 747, CS4K: 748, BS4K: 749, NUM_11: 750, NUM_12: 751 };
+ g[hcap.key.Code.NUM_0] = hcap.key.Code.NUM_0;
+ g[hcap.key.Code.NUM_1] = hcap.key.Code.NUM_1;
+ g[hcap.key.Code.NUM_2] = hcap.key.Code.NUM_2;
+ g[hcap.key.Code.NUM_3] = hcap.key.Code.NUM_3;
+ g[hcap.key.Code.NUM_4] = hcap.key.Code.NUM_4;
+ g[hcap.key.Code.NUM_5] = hcap.key.Code.NUM_5;
+ g[hcap.key.Code.NUM_6] = hcap.key.Code.NUM_6;
+ g[hcap.key.Code.NUM_7] = hcap.key.Code.NUM_7;
+ g[hcap.key.Code.NUM_8] = hcap.key.Code.NUM_8;
+ g[hcap.key.Code.NUM_9] = hcap.key.Code.NUM_9;
+ g[hcap.key.Code.CH_UP] = hcap.key.Code.CH_UP;
+ g[hcap.key.Code.CH_DOWN] = hcap.key.Code.CH_DOWN;
+ g[hcap.key.Code.GUIDE] = hcap.key.Code.GUIDE;
+ g[hcap.key.Code.INFO] = hcap.key.Code.INFO;
+ g[hcap.key.Code.LEFT] = hcap.key.Code.LEFT;
+ g[hcap.key.Code.UP] = hcap.key.Code.UP;
+ g[hcap.key.Code.RIGHT] = hcap.key.Code.RIGHT;
+ g[hcap.key.Code.DOWN] = hcap.key.Code.DOWN;
+ g[hcap.key.Code.ENTER] = 10;
+ g[hcap.key.Code.BACK] = 608;
+ g[hcap.key.Code.EXIT] = 601;
+ g[hcap.key.Code.RED] = hcap.key.Code.RED;
+ g[hcap.key.Code.GREEN] = hcap.key.Code.GREEN;
+ g[hcap.key.Code.YELLOW] = hcap.key.Code.YELLOW;
+ g[hcap.key.Code.BLUE] = hcap.key.Code.BLUE;
+ g[hcap.key.Code.STOP] = hcap.key.Code.STOP;
+ g[hcap.key.Code.PLAY] = hcap.key.Code.PLAY;
+ g[hcap.key.Code.PAUSE] = hcap.key.Code.PAUSE;
+ g[hcap.key.Code.REWIND] = hcap.key.Code.REWIND;
+ g[hcap.key.Code.FAST_FORWARD] = hcap.key.Code.FAST_FORWARD;
+ g[hcap.key.Code.LAST_CH] = 607;
+ g[hcap.key.Code.PORTAL] = hcap.key.Code.PORTAL;
+ g[hcap.key.Code.ORDER] = hcap.key.Code.ORDER;
+ g[hcap.key.Code.MINUS] = 45;
+ g[hcap.key.Code.POWER] = hcap.key.Code.POWER;
+ g[hcap.key.Code.VOL_UP] = hcap.key.Code.VOL_UP;
+ g[hcap.key.Code.VOL_DOWN] = hcap.key.Code.VOL_DOWN;
+ g[hcap.key.Code.MUTE] = hcap.key.Code.MUTE;
+ g[hcap.key.Code.RECORD] = hcap.key.Code.RECORD;
+ g[hcap.key.Code.PAGE_UP] = hcap.key.Code.PAGE_UP;
+ g[hcap.key.Code.PAGE_DOWN] = hcap.key.Code.PAGE_DOWN;
+ g[hcap.key.Code.RF_BYPASS] = 600;
+ g[hcap.key.Code.NEXT_DAY] = 603;
+ g[hcap.key.Code.PREV_DAY] = 604;
+ g[hcap.key.Code.APPS] = 605;
+ g[hcap.key.Code.LINK] = hcap.key.Code.LINK;
+ g[hcap.key.Code.FORWARD] = 609;
+ g[hcap.key.Code.ZOOM] = 610;
+ g[hcap.key.Code.SETTINGS] = hcap.key.Code.SETTINGS;
+ g[hcap.key.Code.NEXT_FAV_CH] = 612;
+ g[hcap.key.Code.RES_1] = 613;
+ g[hcap.key.Code.RES_2] = 614;
+ g[hcap.key.Code.RES_3] = 615;
+ g[hcap.key.Code.RES_4] = 616;
+ g[hcap.key.Code.RES_5] = 617;
+ g[hcap.key.Code.RES_6] = 618;
+ g[hcap.key.Code.LOCK] = hcap.key.Code.LOCK;
+ g[hcap.key.Code.SKIP] = hcap.key.Code.SKIP;
+ g[hcap.key.Code.LIST] = 621;
+ g[hcap.key.Code.LIVE] = hcap.key.Code.LIVE;
+ g[hcap.key.Code.ON_DEMAND] = hcap.key.Code.ON_DEMAND;
+ g[hcap.key.Code.PINP_MOVE] = hcap.key.Code.PINP_MOVE;
+ g[hcap.key.Code.PINP_UP] = hcap.key.Code.PINP_UP;
+ g[hcap.key.Code.PINP_DOWN] = hcap.key.Code.PINP_DOWN;
+ g[hcap.key.Code.MENU] = 627;
+ g[hcap.key.Code.AD] = hcap.key.Code.AD;
+ g[hcap.key.Code.ALARM] = hcap.key.Code.ALARM;
+ g[hcap.key.Code.AV_MODE] = 702;
+ g[hcap.key.Code.SUBTITLE] = 726;
+ g[hcap.key.Code.CC] = 726;
+ g[hcap.key.Code.DISC_POWER_OFF] = hcap.key.Code.DISC_POWER_OFF;
+ g[hcap.key.Code.DISC_POWER_ON] = hcap.key.Code.DISC_POWER_ON;
+ g[hcap.key.Code.DVD] = hcap.key.Code.DVD;
+ g[hcap.key.Code.EJECT] = 708;
+ g[hcap.key.Code.ENERGY_SAVING] = hcap.key.Code.ENERGY_SAVING;
+ g[hcap.key.Code.FAV] = hcap.key.Code.FAV;
+ g[hcap.key.Code.FLASHBK] = hcap.key.Code.FLASHBK;
+ g[hcap.key.Code.INPUT] = hcap.key.Code.INPUT;
+ g[hcap.key.Code.MARK] = hcap.key.Code.MARK;
+ g[hcap.key.Code.NETCAST] = 714;
+ g[hcap.key.Code.PIP] = hcap.key.Code.PIP;
+ g[hcap.key.Code.PIP_CH_DOWN] = hcap.key.Code.PIP_CH_DOWN;
+ g[hcap.key.Code.PIP_CH_UP] = hcap.key.Code.PIP_CH_UP;
+ g[hcap.key.Code.PIP_INPUT] = hcap.key.Code.PIP_INPUT;
+ g[hcap.key.Code.PIP_SWAP] = hcap.key.Code.PIP_SWAP;
+ g[hcap.key.Code.Q_MENU] = 720;
+ g[hcap.key.Code.Q_VIEW] = 721;
+ g[hcap.key.Code.RATIO] = 722;
+ g[hcap.key.Code.SAP] = hcap.key.Code.SAP;
+ g[hcap.key.Code.SIMPLINK] = hcap.key.Code.SIMPLINK;
+ g[hcap.key.Code.STB] = hcap.key.Code.STB;
+ g[hcap.key.Code.T_OPT] = 727;
+ g[hcap.key.Code.TEXT] = 728;
+ g[hcap.key.Code.SLEEP_TIMER] = hcap.key.Code.SLEEP_TIMER;
+ g[hcap.key.Code.TV] = hcap.key.Code.TV;
+ g[hcap.key.Code.TV_RAD] = hcap.key.Code.TV_RAD;
+ g[hcap.key.Code.VCR] = hcap.key.Code.VCR;
+ g[hcap.key.Code.POWER_LOWBATTERY] = hcap.key.Code.POWER_LOWBATTERY;
+ g[hcap.key.Code.SMART_HOME] = hcap.key.Code.SMART_HOME;
+ g[hcap.key.Code.SCREEN_REMOTE] = hcap.key.Code.SCREEN_REMOTE;
+ g[hcap.key.Code.POINTER] = hcap.key.Code.POINTER;
+ g[hcap.key.Code.LG_3D] = hcap.key.Code.LG_3D;
+ g[hcap.key.Code.DATA] = hcap.key.Code.DATA;
+ g[hcap.key.Code.ASSISTIVE_MENU] = hcap.key.Code.ASSISTIVE_MENU;
+ g[hcap.key.Code.THREE_DIGIT_INPUT] = hcap.key.Code.THREE_DIGIT_INPUT;
+ g[hcap.key.Code.LIVETV] = hcap.key.Code.LIVETV;
+ g[hcap.key.Code.GOTOPREV] = hcap.key.Code.GOTOPREV;
+ g[hcap.key.Code.GOTONEXT] = hcap.key.Code.GOTONEXT;
+ g[hcap.key.Code.TER] = hcap.key.Code.TER;
+ g[hcap.key.Code.BS] = hcap.key.Code.BS;
+ g[hcap.key.Code.CS1] = hcap.key.Code.CS1;
+ g[hcap.key.Code.CS2] = hcap.key.Code.CS2;
+ g[hcap.key.Code.CS4K] = hcap.key.Code.CS4K;
+ g[hcap.key.Code.BS4K] = hcap.key.Code.BS4K;
+ g[hcap.key.Code.NUM_11] = hcap.key.Code.NUM_11;
+ g[hcap.key.Code.NUM_12] = hcap.key.Code.NUM_12;
+ hcap.key.addKeyItem = function(r) { r.virtualKeycode = g[r.virtualKeycode];
+ l("add_key_item", r) };
+ hcap.key.removeKeyItem = function(r) { l("remove_key_item", r) };
+ hcap.key.clearKeyTable = function(r) { l("clear_key_table", r) };
+ hcap.key.sendKey = function(r) { r.virtualKeycode = g[r.virtualKeycode];
+ l("send_key", r) };
+ hcap.mouse = {};
+ hcap.mouse.isMouseVisible = function(r) { l("get_mouse_visible", r) };
+ hcap.mouse.setMouseVisible = function(r) { l("set_mouse_visible", r) };
+ hcap.mouse.isPointerOn = function(r) { l("is_pointer_on", r) };
+ hcap.mouse.setPointerOn = function(r) { l("set_pointer_on", r) };
+ hcap.mouse.getPointerPosition = function(r) { l("get_pointer_position", r) };
+ hcap.mouse.setPointerPosition = function(r) { l("set_pointer_position", r) };
+ hcap.mouse.clickPointer = function(r) { l("click_pointer", r) };
+ hcap.mouse.setPointerSize = function(r) { l("set_pointer_size", r) };
+ hcap.property = {};
+ hcap.property.getHotelMode = function(r) { l("get_hotel_mode", r) };
+ hcap.property.setHotelMode = function(r) { l("set_hotel_mode", r) };
+ hcap.property.PicturePropertyKey = { BACKLIGHT: 1, CONTRAST: 2, BRIGHTNESS: 3, SHARPNESS: 4, COLOR: 5, TINT: 6, COLOR_TEMPERATURE: 7, ASPECT_RATIO: 8 };
+ hcap.property.getPictureProperty = function(r) { l("get_picture_property", r) };
+ hcap.property.setPictureProperty = function(r) { l("set_picture_property", r) };
+ hcap.property.PictureMode = { VIVID: 1, STANDARD: 2, ECO: 3, CINEMA: 4, SPORTS: 5, GAME: 6, PHOTO: 7, EXPERT_BRIGHT_ROOM: 8, EXPERT_DARK_ROOM: 9 };
+ hcap.property.getPictureMode = function(r) { l("get_picture_mode", r) };
+ hcap.property.setPictureMode = function(r) { l("set_picture_mode", r) };
+ hcap.property.getProperty = function(r) { l("get_property", r) };
+ hcap.property.setProperty = function(r) { l("set_property", r) };
+ hcap.property.InstallerMenuItem = { INSTALLER_SEQ: 0, POWER_MANAGE: 1, AC_ON: 2, BAND: 3, STRT_CHANNEL: 4, CHAN_LOCK: 5, STRT_VOLUME: 7, MIN_VOLUME: 8, MAX_VOLUME: 9, MUTE_DISABLE: 10, KEY_DEFEAT: 11, IR_BANKS_ENABLE: 12, SCAN_MODE: 13, STRT_CH_IN_SM: 14, SLEEP_TIMER: 15, EN_TIMER: 16, ALARM: 17, FEATURE_LEVEL: 20, V_CHIP: 21, MAX_BLK_HRS: 22, CAPTION_LOCK: 23, FUNCTION_PRE: 25, HOSPITAL_MODE: 27, CH_OVERIDE: 28, REMAP_AUX_INPS: 29, ACK_MASK: 30, POLL_RATE: 31, TIMING_PULSE: 32, COMPORT_EN: 34, HDMI1_ENABLE: 35, REAR_AUX_EN: 39, SIMPLINK_EN: 41, AUTO_INPUTS: 42, STRT_AUX_SRCE: 46, AUX_STATUS: 47, DIS_AUDIO_M: 49, DIS_CH_TIME: 53, EN_CH_T_COL: 69, FOR_CH_TIME: 70, BCK_CH_TIME: 71, CH_NOT_AVBLE: 73, REVERT_CH: 75, QUICK_SHUTOFF: 77, UPN_MSB: 78, UPN_MSB_1: 79, UPN_MSB_2: 80, UPN_LSB: 81, CHKSUM_ERROR: 82, HANDSHK_TIME: 83, PERMANENT_BLK: 84, V_MUTE_TIME: 86, REAR_RGB_EN: 87, EN_NOISE_MUTE: 88, KEY_LOCK: 90, HDMI2_ENABLE: 91, HDMI3_ENABLE: 92, RJP_AVAILABLE: 93, SAP_MENU_EN: 94, DEF_ASP_RATIO: 96, AUDIO_OUTPUT: 97, PROCENTRIC: 98, BACK_LIGHTING: 99, VIDEO_INTERFACE: 100, IR_FEEDBACK: 101, ATSC_BAND: 102, ATSC_TUNE_MODE: 103, START_MINOR_CH: 104, VID_OUT_FORMAT: 105, ASP_RATIO_LOCK: 106, BANNER_SELECT: 107, PANEL_COM: 108, PANEL_HNDSHAKE: 109, PANEL_DELAY: 110, PANEL_VOL_PRE: 111, PANEL_STRT_VOL: 112, PANEL_TYPE: 113, PANEL_MIN_VOL: 114, PANEL_MAX_VOL: 115, VIDEO_MUTE_EN: 116, FACT_DEFAULT: 117, POWER_SAVINGS: 118, DATA_CHANNEL: 119, UPDATE_TIME_HR: 121, UPDATE_TIME_MN: 122 };
+ hcap.property.getInstallerMenuItem = function(r) { l("get_installer_menu_item", r) };
+ hcap.property.setInstallerMenuItem = function(r) { l("set_installer_menu_item", r) };
+ hcap.Media = function() {};
+ hcap.Media.startUp = function(r) { l("media_startup", r) };
+ hcap.Media.shutDown = function(r) { l("media_shutdown", r) };
+ hcap.Media.createMedia = function(r) { if (r === null) { return a } if (a === null && r.url !== null && r.mimeType !== null) { a = new hcap.Media();
+ l("media_create_media", r); return a } return null };
+ hcap.Media.prototype.play = function(r) { if (a === null) { r.onFailure({ errorMessage: "already destroyed." }); return }
+ l("media_play", r) };
+ hcap.Media.prototype.pause = function(r) { if (a === null) { r.onFailure({ errorMessage: "already destroyed." }); return }
+ l("media_pause", r) };
+ hcap.Media.prototype.resume = function(r) { if (a === null) { r.onFailure({ errorMessage: "already destroyed." }); return }
+ l("media_resume", r) };
+ hcap.Media.prototype.stop = function(r) { if (a === null) { r.onFailure({ errorMessage: "already destroyed." }); return }
+ l("media_stop", r) };
+ hcap.Media.prototype.destroy = function(r) { if (a === null) { r.onFailure({ errorMessage: "already destroyed." }); return }
+ l("media_destroy", r);
+ a = null };
+ hcap.Media.prototype.getInformation = function(r) { if (a === null) { r.onFailure({ errorMessage: "already destroyed." }); return }
+ l("media_get_information", r) };
+ hcap.Media.prototype.getPlayPosition = function(r) { if (a === null) { r.onFailure({ errorMessage: "already destroyed." }); return }
+ l("media_get_play_position", r) };
+ hcap.Media.prototype.setPlayPosition = function(r) { if (a === null) { r.onFailure({ errorMessage: "already destroyed." }); return }
+ l("media_set_play_position", r) };
+ hcap.Media.prototype.getPlaySpeed = function(r) { if (a === null) { r.onFailure({ errorMessage: "already destroyed." }); return }
+ l("media_get_play_speed", r) };
+ hcap.Media.prototype.setPlaySpeed = function(r) { if (a === null) { r.onFailure({ errorMessage: "already destroyed." }); return }
+ l("media_set_play_speed", r) };
+ hcap.Media.prototype.setSubtitleOn = function(r) { if (a === null) { r.onFailure({ errorMessage: "already destroyed." }); return }
+ l("media_set_subtitle_on", r) };
+ hcap.Media.prototype.getSubtitleOn = function(r) { if (a === null) { r.onFailure({ errorMessage: "already destroyed." }); return }
+ l("media_get_subtitle_on", r) };
+ hcap.Media.prototype.setSubtitleUrl = function(r) { if (a === null) { r.onFailure({ errorMessage: "already destroyed." }); return }
+ l("media_set_subtitle_url", r) };
+ hcap.Media.prototype.getState = function(r) { if (a === null) { r.onFailure({ errorMessage: "already destroyed." }); return }
+ l("media_get_state", r) };
+ hcap.Media.prototype.getAudioLanguage = function(r) { l("media_get_audio_language", r) };
+ hcap.Media.prototype.setAudioLanguage = function(r) { l("media_set_audio_language", r) };
+ hcap.Media.prototype.getSubtitle = function(r) { if (a === null) { r.onFailure({ errorMessage: "already destroyed." }); return }
+ l("media_get_subtitle", r) };
+ hcap.Media.prototype.setSubtitle = function(r) { if (a === null) { r.onFailure({ errorMessage: "already destroyed." }); return }
+ l("media_set_subtitle", r) };
+ hcap.Media.SubtitleType = { NONE: 0, INTERNAL_SUBTITLE: 1, EXTERNAL_SUBTITLE: 2, CLOSED_CAPTION: 3 };
+ hcap.rms = {};
+ hcap.rms.requestRms = function(r) { l("request_rms", r) };
+ hcap.socket = {};
+ hcap.socket.openUdpDaemon = function(r) { l("open_udp_daemon", r) };
+ hcap.socket.closeUdpDaemon = function(r) { l("close_udp_daemon", r) };
+ hcap.socket.openTcpDaemon = function(r) { l("open_tcp_daemon", r) };
+ hcap.socket.closeTcpDaemon = function(r) { l("close_tcp_daemon", r) };
+ hcap.socket.sendUdpData = function(r) { l("send_udp_data", r) };
+ hcap.drm = {};
+ hcap.drm.securemedia = {};
+ hcap.drm.securemedia.initialize = function(r) { l("secure_media_drm_initialize", r) };
+ hcap.drm.securemedia.unregister = function(r) { l("secure_media_drm_unregister", r) };
+ hcap.drm.securemedia.isRegistration = function(r) { l("secure_media_drm_is_registration", r) };
+ hcap.drm.securemedia.register = function(r) { l("secure_media_drm_register", r) };
+ hcap.drm.securemedia.finalize = function(r) { l("secure_media_drm_finalize", r) };
+ hcap.file = {};
+ hcap.file.getUsbStorageList = function(r) { l("get_usb_storage_list", r) };
+ hcap.file.getUsbStorageFileList = function(r) { l("get_usb_storage_file_list", r) };
+ hcap.file.downloadFileToUsb = function(r) { l("download_file_to_usb", r) };
+ hcap.file.deleteUsbFile = function(r) { l("delete_usb_file", r) };
+ hcap.rs232c = {};
+ hcap.rs232c.BaudRate = { BR_UNKNOWN: 0, BR_110: 110, BR_300: 300, BR_600: 600, BR_1200: 1200, BR_2400: 2400, BR_4800: 4800, BR_9600: 9600, BR_14400: 14400, BR_19200: 19200, BR_38400: 38400, BR_57600: 57600, BR_115200: 115200, BR_128000: 128000, BR_230400: 230400, BR_256000: 256000, BR_512000: 512000, BR_768000: 768000, BR_921600: 921600, BR_1024000: 1024000 };
+ hcap.rs232c.DataBit = { BIT_UNKNOWN: 0, BIT_7: 7, BIT_8: 8 };
+ hcap.rs232c.Parity = { UNKNOWN: 0, NONE: 1, EVEN: 2, ODD: 3 };
+ hcap.rs232c.StopBit = { UNKNOWN: 0, BIT_1: 1, BIT_2: 2 };
+ hcap.rs232c.FlowControl = { UNKNOWN: 0, NONE: 1, XON_XOFF: 2, HARDWARE: 3 };
+ hcap.rs232c.getConfiguration = function(r) { l("rs232c_get_configuration", r) };
+ hcap.rs232c.setConfiguration = function(r) { l("rs232c_set_configuration", r) };
+ hcap.rs232c.sendData = function(r) { l("rs232c_send_data", r) };
+ hcap.rs232c.setStartupData = function(r) { l("rs232c_set_teaching_data", r) };
+ hcap.rs232c.clearStartupData = function(r) { l("rs232c_clear_teaching_data", r) };
+ hcap.system = {};
+ hcap.system.requestScreenCaptureImage = function(r) { l("request_screen_capture_image", r) };
+ hcap.system.getScreenCaptureImage = function(r) { l("get_screen_capture_image", r) };
+ hcap.system.launchHcapHtmlApplication = function(r) { l("launch_hcap_html_application", r) };
+ hcap.system.getMemoryUsage = function(r) { l("get_memory_usage", r) };
+ hcap.system.getCpuUsage = function(r) { l("get_cpu_usage", r) };
+ hcap.system.requestFocus = function(r) { l("request_focus", r) };
+ hcap.system.getFocused = function(r) { l("get_focused", r) };
+ hcap.system.requestCloning = function(r) { l("request_cloning", r) };
+ hcap.system.getLocaleList = function(r) { l("get_locale_list", r) };
+ hcap.system.getLocale = function(r) { l("get_locale", r) };
+ hcap.system.requestLocaleChange = function(r) { l("request_locale_change", r) };
+ hcap.system.getProcentricServer = function(r) { l("get_procentric_server", r) };
+ hcap.system.setProcentricServer = function(r) { l("set_procentric_server", r) };
+ hcap.system.SoundOutputType = { UNKNOWN: 0, INTERNAL_TV_SPEAKER: 1, WIRED_HEADPHONES: 2, OFF: 3, OPTICAL: 4, OPTICAL_LGSOUNDSYNC: 5, EXTERNAL_ARC: 6 };
+ hcap.system.getSoundOutput = function(r) { l("get_sound_output", r) };
+ hcap.system.getDefaultSoundOutput = function(r) { l("get_default_sound_output", r) };
+ hcap.system.setSoundOutput = function(r) { l("set_sound_output", r) };
+ hcap.system.setDefaultSoundOutput = function(r) { l("set_default_sound_output", r) };
+ hcap.system.beginDestroy = function(r) { l("begin_destroy", r) };
+ hcap.system.endDestroy = function(r) { l("end_destroy", r) };
+ hcap.system.getAudioPtsOffset = function(r) { l("get_audio_pts_offset", r) };
+ hcap.system.setAudioPtsOffset = function(r) { l("set_audio_pts_offset", r) };
+ hcap.system.getVideoPtsOffset = function(r) { l("get_video_pts_offset", r) };
+ hcap.system.setVideoPtsOffset = function(r) { l("set_video_pts_offset", r) };
+ hcap.system.getProxyServer = function(r) { l("get_proxy_server", r) };
+ hcap.system.setProxyServer = function(r) { l("set_proxy_server", r) };
+ hcap.system.expireProxyServer = function(r) { l("expire_proxy_server", r) };
+ hcap.system.getBrowserDebugMode = function(r) { l("get_browser_debug_mode", r) };
+ hcap.system.setBrowserDebugMode = function(r) { l("set_browser_debug_mode", r) };
+ hcap.system.getNoSignalImage = function(r) { l("get_no_signal_image", r) };
+ hcap.system.setNoSignalImage = function(r) { l("set_no_signal_image", r) };
+ hcap.system.getScreenKeyboardLanguageList = function(r) { l("get_screen_keyboard_language_list", r) };
+ hcap.system.setScreenKeyboardLanguage = function(r) { l("set_screen_keyboard_language", r) };
+ hcap.system.getUsbPowerControl = function(r) { l("get_usb_power_control", r) };
+ hcap.system.setUsbPowerControl = function(r) { l("set_usb_power_control", r) };
+ hcap.system.showToastMessage = function(r) { l("show_toast_message", r) };
+ hcap.system.startManualUpdate = function(r) { l("start_manual_update", r) };
+ hcap.system.cancelUpdate = function(r) { l("cancel_update", r) };
+ hcap.system.getUpdateProgress = function(r) { l("get_update_progress", r) };
+ hcap.checkout = {};
+ hcap.checkout.requestCheckout = function(r) { l("request_checkout", r) };
+ hcap.checkout.takeCheckoutSnapshot = function(r) { l("take_checkout_snapshot", r) };
+ hcap.beacon = {};
+ hcap.beacon.setBeaconMode = function(r) { l("set_beacon_mode", r) };
+ hcap.beacon.requestiBeacon = function(r) { l("request_iBeacon", r) };
+ hcap.beacon.requestEddystoneUid = function(r) { l("request_eddystone_uid", r) };
+ hcap.beacon.requestEddystoneUrl = function(r) { l("request_eddystone_url", r) };
+ hcap.beacon.getBeaconInformation = function(r) { l("get_beacon_information", r) };
+ hcap.bluetooth = {};
+ hcap.bluetooth.setScanState = function(r) { l("bt_gap_set_scan_state", r) };
+ hcap.bluetooth.disconnect = function(r) { l("bt_service_disconnect", r) };
+ hcap.bluetooth.setBluetoothSoundSync = function(r) { l("set_bt_sound_sync", r) };
+ hcap.bluetooth.getBluetoothSoundSync = function(r) { l("get_bt_sound_sync", r) };
+ hcap.bluetooth.audio = {};
+ hcap.bluetooth.audio.play = function(r) { l("bt_audio_play", r) };
+ hcap.bluetooth.audio.stop = function(r) { l("bt_audio_stop", r) };
+ hcap.bluetooth.audio.pause = function(r) { l("bt_audio_pause", r) };
+ hcap.bluetooth.audio.forward = function(r) { l("bt_audio_forward", r) };
+ hcap.bluetooth.audio.backward = function(r) { l("bt_audio_backward", r) };
+ hcap.webrtc = {};
+ hcap.webrtc.startPreviewVideo = function(r) { l("webrtc_start_preview_video", r) };
+ hcap.webrtc.stopPreviewVideo = function(r) { l("webrtc_stop_preview_video", r) };
+ hcap.webrtc.incomingCall = function(r) { l("webrtc_incoming_call", r) };
+ hcap.webrtc.outgoingCall = function(r) { l("webrtc_outgoing_call", r) };
+ hcap.webrtc.endCall = function(r) { l("webrtc_end_call", r) };
+ hcap.webrtc.acceptMessage = function(r) { l("webrtc_accept_message", r) };
+ hcap.webrtc.startCheckAudio = function(r) { l("webrtc_start_check_audio", r) };
+ hcap.webrtc.stopCheckAudio = function(r) { l("webrtc_stop_check_audio", r) };
+ hcap.webrtc.setConfiguration = function(r) { l("webrtc_set_configuration", r) };
+ hcap.webrtc.getConfiguration = function(r) { l("webrtc_get_configuration", r) };
+ hcap.webrtc.showDiagnostics = function(r) { l("webrtc_show_diagnostics", r) };
+ hcap.security = {};
+ hcap.security.registerServerCertificate = function(r) { l("register_server_certificate", r) };
+ hcap.security.registerClientCertificate = function(r) { l("register_client_certificate", r) };
+ hcap.security.unregisterServerCertificate = function(r) { l("unregister_server_certificate", r) };
+ hcap.security.unregisterClientCertificate = function(r) { l("unregister_client_certificate", r) };
+ hcap.security.existServerCertificate = function(r) { l("exist_server_certificate", r) };
+ hcap.security.existClientCertificate = function(r) { l("exist_client_certificate", r) };
+ hcap.iot = {};
+ hcap.iot.requestSetBridgeStatus = function(r) { l("iot_request_set_bridge_status", r) };
+ hcap.iot.getBridgeStatus = function(r) { l("iot_get_bridge_status", r) };
+ hcap.iot.requestRegisterThing = function(r) { l("iot_request_register_thing", r) };
+ hcap.iot.requestRejectThing = function(r) { l("iot_request_reject_thing", r) };
+ hcap.iot.getThingList = function(r) { l("iot_get_thing_list", r) };
+ hcap.iot.getBindingIdList = function(r) { l("iot_get_binding_id_list", r) };
+ hcap.iot.requestSetComponent = function(r) { l("iot_request_set_component", r) };
+ hcap.iot.requestUnregisterThing = function(r) { l("iot_request_unregister_thing", r) };
+ hcap.iot.setThingNickname = function(r) { l("iot_set_thing_nickname", r) };
+ hcap.iot.requestSynchronizeThing = function(r) { l("iot_request_synchronize_thing", r) };
+ hcap.iot.getFrameworkStatus = function(r) { l("iot_get_framework_status", r) };
+ hcap.iot.requestFactoryReset = function(r) { l("iot_request_factory_reset", r) };
+ hcap.iot.getVersions = function(r) { l("iot_get_versions", r) };
+ hcap.iot.getThingListPrivate = function(r) { l("iot_get_thing_list_private", r) };
+ hcap.speech = {};
+ hcap.speech.setSpeechRecognition = function(r) { l("set_speech_recognition", r) };
+ hcap.speech.getSpeechRecognition = function(r) { l("get_speech_recognition", r) };
+ hcap.speech.HostType = { NOT_SUPPORT: 0, APPLICATION: 1, TV: 2 };
+ hcap.speech.decideHost = function(r) { l("decide_host", r) } }()) };
\ No newline at end of file
diff --git a/procentric/application/lib/hcap.js b/procentric/application/lib/hcap.js
new file mode 100755
index 0000000..b4600d8
--- /dev/null
+++ b/procentric/application/lib/hcap.js
@@ -0,0 +1,9 @@
+/*!
+ * ============================================================================
+ * Creative Innovation Center, LG ELECTRONICS INC., SEOUL, KOREA
+ * Copyright(c) 2018 by LG Electronics Inc.
+ *
+ * Release Version : 1.24.6.5901
+ * ============================================================================
+ */
+var extHcapSecure;var extRegisterHcapCloseHandler;var extDisableHcapConsoleLog;var extWebWorker;var hcap;if(hcap===undefined){(function(){hcap={API_VERSION:"1.24.6.5901"};var g=[],e=0,i=[{command_id:"0",param_text:'{"command_id" : "0", "command" : "notify_sdk_version", "hcap_js_extension_version" : "1.24.6.5901"}'}],k=null,o=false,d=false,n=false,c=null,f=null,l=null,b=false,m=null,a=null;function j(r){if(extDisableHcapConsoleLog!==true){var t;if(r.length>1024){t=r.substring(0,1024)}else{t=r}if(extWebWorker!==true){console.log(t)}}}if(extDisableHcapConsoleLog===true){if(extWebWorker!==true){console.log("hcap console log is disabled")}}else{if(extWebWorker!==true){console.log("hcap console log is enabled")}}j("check external value : extDisableHcapConsoleLog = "+extDisableHcapConsoleLog+", extHcapSecure = "+extHcapSecure+", extRegisterHcapCloseHandler = "+extRegisterHcapCloseHandler);function p(){var r=navigator.userAgent,t=r.match(/Windows/),s=r.match(/Macintosh/),u=r.match(/Mac OS X/);j("UA = '"+r+"'");if(t||s||u){j("HCAP websocket off");return true}return false}b=p();function h(r,x,s,y){var v="",t="",u="";u=x[r];try{v=s[u];t=typeof v}catch(w){v="";t="unknown"}if(t==="function"){v="{/*function*/}"}else{if(t==="object"){v=m("",v)}else{if(t==="string"){v='"'+v+'"'}}}y+='"'+u+'" : '+v;if(r0&&i[0].command_id===s){j(m("command_id = "+s+" received, ",w));if(u){if(i[0].onSuccess){try{i[0].onSuccess(w)}catch(t){j(m("exception : onSuccess : "+t))}}}else{if(i[0].onFailure){try{i[0].onFailure(w)}catch(t){j(m("exception : onFailure : "+t))}}}i.splice(0,1);n=false;f()}else{j(m("invalid response from server ",w));n=false;f()}}};k.onclose=function(){j("websocket : onclose");d=false;o=false;n=false;setTimeout(f,50)};if(extRegisterHcapCloseHandler==="onbeforeunload"){window.onbeforeunload=function(){j("close hcap websocket in onbeforeunload handler");k.onclose=function(){return undefined};k.close()}}else{if(extRegisterHcapCloseHandler==="onunload"){window.onunload=function(){j("close hcap websocket in onunload handler");k.onclose=function(){return undefined};k.close()}}}};f=function(){if(n){return}n=true;if(o){if(i.length>0){j(m("command_id = "+i[0].command_id+" sent, ",JSON.parse(i[0].param_text)));k.send(i[0].param_text);return}}else{c()}n=false};l=function(u,t){if(u===null||u===""||u===undefined){j('[ERROR] command should not null or empty string! command === null || command === "" || command === undefined');return}if(Object.prototype.toString.call(t)==="[object Array]"){j("[ERROR] param should be Object type({})! param is Array. command = "+u);return}if(t===null||t===undefined){j("[ERROR] param should be Object type({})! param === null || param === undefined. command = "+u);return}if(b){if(t.onFailure){t.onFailure({errorMessage:"HCAP WebSocket is not available in this browser"})}return}if(e>1024){e=0}else{e+=1}var r=e.toString(),s="";t.command_id=r;t.command=u;s=JSON.stringify(t,null);i[i.length]={command_id:r,param_text:s,onSuccess:t.onSuccess,onFailure:t.onFailure};j(m("command_id = "+r+" added, ",i[i.length-1]));f()};if(!b){setTimeout(f,200)}hcap.preloadedApplication={};hcap.preloadedApplication.getPreloadedApplicationList=function(r){l("get_preloaded_application_list",r)};hcap.preloadedApplication.launchPreloadedApplication=function(r){l("launch_preloaded_application",r)};hcap.preloadedApplication.destroyPreloadedApplication=function(r){l("destroy_preloaded_application",r)};hcap.application={};hcap.application.getServiceXml=function(r){l("get_service_xml",r)};hcap.application.getDefaultServiceXml=function(r){l("get_default_service_xml",r)};hcap.application.getApplicationList=function(r){l("get_application_list",r)};hcap.application.launchApplication=function(r){l("launch_application",r)};hcap.application.destroyApplication=function(r){l("destroy_application",r)};hcap.application.installApplications=function(r){l("install_applications",r)};hcap.application.removeApplications=function(r){l("remove_applications",r)};hcap.application.RegisterSIApplicationList=function(r){l("register_si_app_list",r)};hcap.video={};hcap.video.getVideoSize=function(r){l("get_video_size",r)};hcap.video.setVideoSize=function(r){l("set_video_size",r)};hcap.video.getOsdTransparencyLevel=function(r){l("get_osd_transparency_level",r)};hcap.video.setOsdTransparencyLevel=function(r){l("set_osd_transparency_level",r)};hcap.video.isVideoMute=function(r){l("get_video_mute",r)};hcap.video.setVideoMute=function(r){l("set_video_mute",r)};hcap.volume={};hcap.volume.getVolumeLevel=function(r){l("get_volume_level",r)};hcap.volume.setVolumeLevel=function(r){l("set_volume_level",r)};hcap.volume.getExternalSpeakerVolumeLevel=function(r){l("get_external_speaker_volume_level",r)};hcap.volume.setExternalSpeakerVolumeLevel=function(r){l("set_external_speaker_volume_level",r)};hcap.volume.getHeadphoneVolumeLevel=function(r){l("get_headphone_volume_level",r)};hcap.volume.setHeadphoneVolumeLevel=function(r){l("set_headphone_volume_level",r)};hcap.volume.setHealthcareHeadphoneMode=function(r){l("set_healthcare_headphone_mode",r)};hcap.volume.getHealthcareHeadphoneMode=function(r){l("get_healthcare_headphone_mode",r)};hcap.channel={};hcap.channel.NO_STREAM_PID=8191;hcap.channel.ChannelType={UNKNOWN:0,RF:1,IP:2,RF_DATA:3,IP_DATA:4};hcap.channel.Polarization={UNKNOWN:0,VERTICAL:1,HORIZONTAL:2,LEFT_HAND_CIRCULAR:3,RIGHT_HAND_CIRCULAR:4};hcap.channel.RfBroadcastType={UNKNOWN:0,TERRESTRIAL:16,TERRESTRIAL_2:17,SATELLITE:32,SATELLITE_2:33,SATELLITE_CS1:34,SATELLITE_CS2:35,SATELLITE_S3_BS:36,SATELLITE_S3_CS:37,CABLE:48,CABLE_STD:49,CABLE_HRC:50,CABLE_IRC:51,ANALOG_PAL_BG:64,ANALOG_PAL_DK:65,ANALOG_PAL_I:66,ANALOG_PAL_M:67,ANALOG_PAL_N:68,ANALOG_SECAM_BG:69,ANALOG_SECAM_DK:70,ANALOG_SECAM_L:71,ANALOG_NTSC:72,TERRESTRIAL_ATSC3:80,CABLE_ATSC3:81};hcap.channel.IpBroadcastType={UNKNOWN:0,UDP:16,RTP:32};hcap.channel.VideoStreamType={MPEG1:1,MPEG2:2,MPEG4_VISUAL:16,MPEG4_AVC_H264:27,HEVC:36,AVS:66};hcap.channel.AudioStreamType={MPEG1:3,MPEG2:4,MPEG2_AAC:15,MPEG4_HEAAC:17,AC3:129,EAC3:130,ANALOG_BG:256,ANALOG_I:257,ANALOG_DK:258,ANALOG_L:259,ANALOG_MN:260,ANALOG_LP:261,ANALOG_END:262};hcap.channel.InbandDataServiceType={UNKNOWN:0,MHP:1,MHEG:2,HBBTV:3,NONE:4};hcap.channel.ChannelStatus={UNKNOWN:0,AUDIO_VIDEO_NOT_BLOCKED:16,AV_DISPLAYED:16,AUDIO_VIDEO_BLOCKED:33,NO_SIGNAL:33,AUDIO_ONLY_BLOCKED:34,VIDEO_ONLY_BLOCKED:35};hcap.channel.requestChangeCurrentChannel=function(r){l("request_channel_change",r)};hcap.channel.getCurrentChannel=function(r){l("get_current_channel",r)};hcap.channel.replayCurrentChannel=function(r){l("replay_current_channel",r)};hcap.channel.stopCurrentChannel=function(r){l("stop_current_channel",r)};hcap.channel.getDataChannel=function(r){l("get_data_channel",r)};hcap.channel.getChannelMap=function(r){l("get_channel_map",r)};hcap.channel.getStartChannel=function(r){l("get_start_channel",r)};hcap.channel.setStartChannel=function(r){l("set_start_channel",r)};hcap.channel.getCurrentChannelAudioLanguageList=function(r){l("get_current_channel_audio_language_list",r)};hcap.channel.getCurrentChannelAudioLanguageIndex=function(r){l("get_current_channel_audio_language_index",r)};hcap.channel.setCurrentChannelAudioLanguageIndex=function(r){l("set_current_channel_audio_language_index",r)};hcap.channel.getCurrentChannelSubtitleList=function(r){l("get_current_channel_subtitle_language_list",r)};hcap.channel.getCurrentChannelSubtitleIndex=function(r){l("get_current_channel_subtitle_language_index",r)};hcap.channel.setCurrentChannelSubtitleIndex=function(r){l("set_current_channel_subtitle_language_index",r)};hcap.channel.getProgramInfo=function(r){l("get_program_info",r)};hcap.channel.launchInbandDataService=function(r){l("launch_inband_data_service",r)};hcap.channel.getReadyInbandDataService=function(r){l("get_ready_inband_data_service",r)};hcap.channel.getChannelSignalStatus=function(r){l("get_channel_signal_status",r)};hcap.externalinput={};hcap.externalinput.ExternalInputType={TV:1,COMPOSITE:2,SVIDEO:3,COMPONENT:4,RGB:5,HDMI:6,SCART:7,USB:8,OTHERS:9};hcap.externalinput.getCurrentExternalInput=function(r){l("get_external_input",r)};hcap.externalinput.setCurrentExternalInput=function(r){l("set_external_input",r)};hcap.externalinput.isExternalInputConnected=function(r){l("check_external_input_connected",r)};hcap.externalinput.getExternalInputList=function(r){l("get_external_input_list",r)};hcap.carousel={};hcap.carousel.requestCacheCarouselData=function(r){l("request_content",r)};hcap.carousel.isCarouselDataCached=function(r){l("is_content_loaded",r)};hcap.carousel.clearCarouselDataCache=function(r){l("clear_content_cache",r)};hcap.mpi={};hcap.mpi.sendAndReceiveMpiData=function(r){l("send_and_receive_mpi_data",r)};hcap.mpi.sendMpiData=function(r){l("send_mpi_data",r)};hcap.power={};hcap.power.PowerMode={WARM:2,NORMAL:1};hcap.power.getPowerMode=function(r){l("get_power_mode",r)};hcap.power.setPowerMode=function(r){l("set_power_mode",r)};hcap.power.isWarmUpdate=function(r){l("is_power_warm_update",r)};hcap.power.powerOff=function(r){l("power_off",r)};hcap.power.reboot=function(r){l("reboot",r)};hcap.time={};hcap.time.setLocalTime=function(r){l("set_tv_localtime",r)};hcap.time.getLocalTime=function(r){l("get_tv_localtime",r)};hcap.time.getPowerOffTimer=function(r){l("get_power_off_timer_in_min",r)};hcap.time.setPowerOffTimer=function(r){l("set_power_off_timer_in_min",r)};hcap.time.getPowerOnTime=function(r){l("get_power_on_time",r)};hcap.time.setPowerOnTime=function(r){l("set_power_on_time",r)};hcap.time.getAlarmInformation=function(r){l("get_alarm_information",r)};hcap.time.setAlarmInformation=function(r){l("set_alarm_information",r)};hcap.time.getCpuTime=function(r){l("get_cpu_time",r)};hcap.network={};hcap.network.getNumberOfNetworkDevices=function(r){l("get_number_of_network_devices",r)};hcap.network.getNetworkDevice=function(r){l("get_network_device",r)};hcap.network.setNetworkDevice=function(r){l("set_network_device",r)};hcap.network.ping=function(r){l("ping",r)};hcap.network.NetworkEventType={UNKNOWN:0,ETHERNET_PLUGGED:1,ETHERNET_UNPLUGGED:2,WIFI_DONGLE_PLUGGED:3,WIFI_DONGLE_UNPLUGGED:4,IP_CONFLICT:5,IP_NOT_CONFLICT:6,DHCP_SUCCESS:7,DHCP_FAIL:8,UNABLE_REACH_GATEWAY:9,ABLE_REACH_GATEWAY:10,UNABLE_REACH_DNS:11,ABLE_REACH_DNS:12,UNABLE_REACH_INTERNET:13,ABLE_REACH_INTERNET:14,WIFI_AP_SEARCH_COMPLETE:15,WIFI_CONNECTED:16,WIFI_CONNECT_FAIL:17,WIFI_LINK_DROPPED:18};hcap.network.NetworkMode={UNKNOWN:0,WIRE:1,WIRELESS:2,NOT_REACHABLE:3};hcap.network.WirelessMode={UNKNOWN:0,INFRA:1,ADHOC:2};hcap.network.WifiSecurityType={UNKNOWN:0,OPEN:1,WEP:2,WPA_PSK_TKIP:3,WPA_PSK_AES:4,WPA2_PSK_TKIP:5,WPA2_PSK_AES:6,WPA12_PSK_AES_TKIPAES:7};hcap.network.DhcpState={UNKNOWN:0,INIT:1,SELECTING:2,REQUESTING:3,BOUND:4,RENEWING:5,REBINDING:6,INIT_REBOOT:7,REBOOTING:8};hcap.network.getNetworkInformation=function(r){l("get_network_information",r)};hcap.network.getSoftAP=function(r){l("get_soft_ap",r)};hcap.network.setSoftAP=function(r){l("set_soft_ap",r)};hcap.network.getWifiDiagnostics=function(r){l("get_wifi_diagnostics",r)};hcap.network.asyncPing=function(r){l("async_ping",r)};hcap.network.setVlanIdMode=function(r){l("set_vlan_id_mode",r)};hcap.network.getVlanIdMode=function(r){l("get_vlan_id_mode",r)};hcap.network.getLanId=function(r){l("get_lan_id",r)};hcap.network.setLanId=function(r){l("set_lan_id",r)};hcap.network.getAuxLanId=function(r){l("get_aux_lan_id",r)};hcap.network.setAuxLanId=function(r){l("set_aux_lan_id",r)};hcap.network.getBlockedPortList=function(r){l("get_blocked_port_list",r)};hcap.network.setBlockedPortList=function(r){l("set_blocked_port_list",r)};hcap.mode={};hcap.mode.HCAP_MODE_0=257;hcap.mode.HCAP_MODE_1=258;hcap.mode.HCAP_MODE_2=259;hcap.mode.HCAP_MODE_3=260;hcap.mode.HCAP_MODE_4=261;hcap.mode.getHcapMode=function(r){l("get_mw_mode",r)};hcap.mode.setHcapMode=function(r){l("set_mw_mode",r)};hcap.key={};hcap.key.Code={NUM_0:48,NUM_1:49,NUM_2:50,NUM_3:51,NUM_4:52,NUM_5:53,NUM_6:54,NUM_7:55,NUM_8:56,NUM_9:57,CH_UP:427,CH_DOWN:428,GUIDE:458,INFO:457,LEFT:37,UP:38,RIGHT:39,DOWN:40,ENTER:13,BACK:461,EXIT:1001,RED:403,GREEN:404,YELLOW:405,BLUE:406,STOP:413,PLAY:415,PAUSE:19,REWIND:412,FAST_FORWARD:417,LAST_CH:711,PORTAL:602,ORDER:623,MINUS:704,POWER:409,VOL_UP:447,VOL_DOWN:448,MUTE:449,RECORD:416,PAGE_UP:33,PAGE_DOWN:34,RF_BYPASS:29,NEXT_DAY:425,PREV_DAY:424,APPS:93,LINK:606,FORWARD:167,ZOOM:251,SETTINGS:611,NEXT_FAV_CH:176,RES_1:112,RES_2:113,RES_3:114,RES_4:115,RES_5:116,RES_6:117,LOCK:619,SKIP:620,LIST:1006,LIVE:622,ON_DEMAND:623,PINP_MOVE:624,PINP_UP:625,PINP_DOWN:626,MENU:18,AD:700,ALARM:701,AV_MODE:31,SUBTITLE:460,CC:1008,DISC_POWER_OFF:705,DISC_POWER_ON:706,DVD:707,EJECT:414,ENERGY_SAVING:709,FAV:710,FLASHBK:711,INPUT:712,MARK:713,NETCAST:1000,PIP:715,PIP_CH_DOWN:716,PIP_CH_UP:717,PIP_INPUT:718,PIP_SWAP:719,Q_MENU:1002,Q_VIEW:1007,RATIO:1005,SAP:723,SIMPLINK:724,STB:725,T_OPT:1004,TEXT:459,SLEEP_TIMER:729,TV:730,TV_RAD:731,VCR:732,POWER_LOWBATTERY:733,SMART_HOME:734,SCREEN_REMOTE:735,POINTER:736,LG_3D:737,DATA:738,ASSISTIVE_MENU:739,THREE_DIGIT_INPUT:740,LIVETV:741,GOTOPREV:742,GOTONEXT:743,TER:744,BS:745,CS1:746,CS2:747,CS4K:748,BS4K:749,NUM_11:750,NUM_12:751,NETFLIX:1037};g[hcap.key.Code.NUM_0]=hcap.key.Code.NUM_0;g[hcap.key.Code.NUM_1]=hcap.key.Code.NUM_1;g[hcap.key.Code.NUM_2]=hcap.key.Code.NUM_2;g[hcap.key.Code.NUM_3]=hcap.key.Code.NUM_3;g[hcap.key.Code.NUM_4]=hcap.key.Code.NUM_4;g[hcap.key.Code.NUM_5]=hcap.key.Code.NUM_5;g[hcap.key.Code.NUM_6]=hcap.key.Code.NUM_6;g[hcap.key.Code.NUM_7]=hcap.key.Code.NUM_7;g[hcap.key.Code.NUM_8]=hcap.key.Code.NUM_8;g[hcap.key.Code.NUM_9]=hcap.key.Code.NUM_9;g[hcap.key.Code.CH_UP]=hcap.key.Code.CH_UP;g[hcap.key.Code.CH_DOWN]=hcap.key.Code.CH_DOWN;g[hcap.key.Code.GUIDE]=hcap.key.Code.GUIDE;g[hcap.key.Code.INFO]=hcap.key.Code.INFO;g[hcap.key.Code.LEFT]=hcap.key.Code.LEFT;g[hcap.key.Code.UP]=hcap.key.Code.UP;g[hcap.key.Code.RIGHT]=hcap.key.Code.RIGHT;g[hcap.key.Code.DOWN]=hcap.key.Code.DOWN;g[hcap.key.Code.ENTER]=10;g[hcap.key.Code.BACK]=608;g[hcap.key.Code.EXIT]=601;g[hcap.key.Code.RED]=hcap.key.Code.RED;g[hcap.key.Code.GREEN]=hcap.key.Code.GREEN;g[hcap.key.Code.YELLOW]=hcap.key.Code.YELLOW;g[hcap.key.Code.BLUE]=hcap.key.Code.BLUE;g[hcap.key.Code.STOP]=hcap.key.Code.STOP;g[hcap.key.Code.PLAY]=hcap.key.Code.PLAY;g[hcap.key.Code.PAUSE]=hcap.key.Code.PAUSE;g[hcap.key.Code.REWIND]=hcap.key.Code.REWIND;g[hcap.key.Code.FAST_FORWARD]=hcap.key.Code.FAST_FORWARD;g[hcap.key.Code.LAST_CH]=607;g[hcap.key.Code.PORTAL]=hcap.key.Code.PORTAL;g[hcap.key.Code.ORDER]=hcap.key.Code.ORDER;g[hcap.key.Code.MINUS]=45;g[hcap.key.Code.POWER]=hcap.key.Code.POWER;g[hcap.key.Code.VOL_UP]=hcap.key.Code.VOL_UP;g[hcap.key.Code.VOL_DOWN]=hcap.key.Code.VOL_DOWN;g[hcap.key.Code.MUTE]=hcap.key.Code.MUTE;g[hcap.key.Code.RECORD]=hcap.key.Code.RECORD;g[hcap.key.Code.PAGE_UP]=hcap.key.Code.PAGE_UP;g[hcap.key.Code.PAGE_DOWN]=hcap.key.Code.PAGE_DOWN;g[hcap.key.Code.RF_BYPASS]=600;g[hcap.key.Code.NEXT_DAY]=603;g[hcap.key.Code.PREV_DAY]=604;g[hcap.key.Code.APPS]=605;g[hcap.key.Code.LINK]=hcap.key.Code.LINK;g[hcap.key.Code.FORWARD]=609;g[hcap.key.Code.ZOOM]=610;g[hcap.key.Code.SETTINGS]=hcap.key.Code.SETTINGS;g[hcap.key.Code.NEXT_FAV_CH]=612;g[hcap.key.Code.RES_1]=613;g[hcap.key.Code.RES_2]=614;g[hcap.key.Code.RES_3]=615;g[hcap.key.Code.RES_4]=616;g[hcap.key.Code.RES_5]=617;g[hcap.key.Code.RES_6]=618;g[hcap.key.Code.LOCK]=hcap.key.Code.LOCK;g[hcap.key.Code.SKIP]=hcap.key.Code.SKIP;g[hcap.key.Code.LIST]=621;g[hcap.key.Code.LIVE]=hcap.key.Code.LIVE;g[hcap.key.Code.ON_DEMAND]=hcap.key.Code.ON_DEMAND;g[hcap.key.Code.PINP_MOVE]=hcap.key.Code.PINP_MOVE;g[hcap.key.Code.PINP_UP]=hcap.key.Code.PINP_UP;g[hcap.key.Code.PINP_DOWN]=hcap.key.Code.PINP_DOWN;g[hcap.key.Code.MENU]=627;g[hcap.key.Code.AD]=hcap.key.Code.AD;g[hcap.key.Code.ALARM]=hcap.key.Code.ALARM;g[hcap.key.Code.AV_MODE]=702;g[hcap.key.Code.SUBTITLE]=726;g[hcap.key.Code.CC]=726;g[hcap.key.Code.DISC_POWER_OFF]=hcap.key.Code.DISC_POWER_OFF;g[hcap.key.Code.DISC_POWER_ON]=hcap.key.Code.DISC_POWER_ON;g[hcap.key.Code.DVD]=hcap.key.Code.DVD;g[hcap.key.Code.EJECT]=708;g[hcap.key.Code.ENERGY_SAVING]=hcap.key.Code.ENERGY_SAVING;g[hcap.key.Code.FAV]=hcap.key.Code.FAV;g[hcap.key.Code.FLASHBK]=hcap.key.Code.FLASHBK;g[hcap.key.Code.INPUT]=hcap.key.Code.INPUT;g[hcap.key.Code.MARK]=hcap.key.Code.MARK;g[hcap.key.Code.NETCAST]=714;g[hcap.key.Code.PIP]=hcap.key.Code.PIP;g[hcap.key.Code.PIP_CH_DOWN]=hcap.key.Code.PIP_CH_DOWN;g[hcap.key.Code.PIP_CH_UP]=hcap.key.Code.PIP_CH_UP;g[hcap.key.Code.PIP_INPUT]=hcap.key.Code.PIP_INPUT;g[hcap.key.Code.PIP_SWAP]=hcap.key.Code.PIP_SWAP;g[hcap.key.Code.Q_MENU]=720;g[hcap.key.Code.Q_VIEW]=721;g[hcap.key.Code.RATIO]=722;g[hcap.key.Code.SAP]=hcap.key.Code.SAP;g[hcap.key.Code.SIMPLINK]=hcap.key.Code.SIMPLINK;g[hcap.key.Code.STB]=hcap.key.Code.STB;g[hcap.key.Code.T_OPT]=727;g[hcap.key.Code.TEXT]=728;g[hcap.key.Code.SLEEP_TIMER]=hcap.key.Code.SLEEP_TIMER;g[hcap.key.Code.TV]=hcap.key.Code.TV;g[hcap.key.Code.TV_RAD]=hcap.key.Code.TV_RAD;g[hcap.key.Code.VCR]=hcap.key.Code.VCR;g[hcap.key.Code.POWER_LOWBATTERY]=hcap.key.Code.POWER_LOWBATTERY;g[hcap.key.Code.SMART_HOME]=hcap.key.Code.SMART_HOME;g[hcap.key.Code.SCREEN_REMOTE]=hcap.key.Code.SCREEN_REMOTE;g[hcap.key.Code.POINTER]=hcap.key.Code.POINTER;g[hcap.key.Code.LG_3D]=hcap.key.Code.LG_3D;g[hcap.key.Code.DATA]=hcap.key.Code.DATA;g[hcap.key.Code.ASSISTIVE_MENU]=hcap.key.Code.ASSISTIVE_MENU;g[hcap.key.Code.THREE_DIGIT_INPUT]=hcap.key.Code.THREE_DIGIT_INPUT;g[hcap.key.Code.LIVETV]=hcap.key.Code.LIVETV;g[hcap.key.Code.GOTOPREV]=hcap.key.Code.GOTOPREV;g[hcap.key.Code.GOTONEXT]=hcap.key.Code.GOTONEXT;g[hcap.key.Code.TER]=hcap.key.Code.TER;g[hcap.key.Code.BS]=hcap.key.Code.BS;g[hcap.key.Code.CS1]=hcap.key.Code.CS1;g[hcap.key.Code.CS2]=hcap.key.Code.CS2;g[hcap.key.Code.CS4K]=hcap.key.Code.CS4K;g[hcap.key.Code.BS4K]=hcap.key.Code.BS4K;g[hcap.key.Code.NUM_11]=hcap.key.Code.NUM_11;g[hcap.key.Code.NUM_12]=hcap.key.Code.NUM_12;g[hcap.key.Code.NETFLIX]=752;hcap.key.addKeyItem=function(r){r.virtualKeycode=g[r.virtualKeycode];l("add_key_item",r)};hcap.key.removeKeyItem=function(r){l("remove_key_item",r)};hcap.key.clearKeyTable=function(r){l("clear_key_table",r)};hcap.key.sendKey=function(r){r.virtualKeycode=g[r.virtualKeycode];l("send_key",r)};hcap.mouse={};hcap.mouse.isMouseVisible=function(r){l("get_mouse_visible",r)};hcap.mouse.setMouseVisible=function(r){l("set_mouse_visible",r)};hcap.mouse.isPointerOn=function(r){l("is_pointer_on",r)};hcap.mouse.setPointerOn=function(r){l("set_pointer_on",r)};hcap.mouse.getPointerPosition=function(r){l("get_pointer_position",r)};hcap.mouse.setPointerPosition=function(r){l("set_pointer_position",r)};hcap.mouse.clickPointer=function(r){l("click_pointer",r)};hcap.mouse.setPointerSize=function(r){l("set_pointer_size",r)};hcap.property={};hcap.property.getHotelMode=function(r){l("get_hotel_mode",r)};hcap.property.setHotelMode=function(r){l("set_hotel_mode",r)};hcap.property.PicturePropertyKey={BACKLIGHT:1,CONTRAST:2,BRIGHTNESS:3,SHARPNESS:4,COLOR:5,TINT:6,COLOR_TEMPERATURE:7,ASPECT_RATIO:8};hcap.property.getPictureProperty=function(r){l("get_picture_property",r)};hcap.property.setPictureProperty=function(r){l("set_picture_property",r)};hcap.property.PictureMode={VIVID:1,STANDARD:2,ECO:3,CINEMA:4,SPORTS:5,GAME:6,PHOTO:7,EXPERT_BRIGHT_ROOM:8,EXPERT_DARK_ROOM:9};hcap.property.getPictureMode=function(r){l("get_picture_mode",r)};hcap.property.setPictureMode=function(r){l("set_picture_mode",r)};hcap.property.getProperty=function(r){l("get_property",r)};hcap.property.setProperty=function(r){l("set_property",r)};hcap.property.InstallerMenuItem={INSTALLER_SEQ:0,POWER_MANAGE:1,AC_ON:2,BAND:3,STRT_CHANNEL:4,CHAN_LOCK:5,STRT_VOLUME:7,MIN_VOLUME:8,MAX_VOLUME:9,MUTE_DISABLE:10,KEY_DEFEAT:11,IR_BANKS_ENABLE:12,SCAN_MODE:13,STRT_CH_IN_SM:14,SLEEP_TIMER:15,EN_TIMER:16,ALARM:17,FEATURE_LEVEL:20,V_CHIP:21,MAX_BLK_HRS:22,CAPTION_LOCK:23,FUNCTION_PRE:25,HOSPITAL_MODE:27,CH_OVERIDE:28,REMAP_AUX_INPS:29,ACK_MASK:30,POLL_RATE:31,TIMING_PULSE:32,COMPORT_EN:34,HDMI1_ENABLE:35,REAR_AUX_EN:39,SIMPLINK_EN:41,AUTO_INPUTS:42,STRT_AUX_SRCE:46,AUX_STATUS:47,DIS_AUDIO_M:49,DIS_CH_TIME:53,EN_CH_T_COL:69,FOR_CH_TIME:70,BCK_CH_TIME:71,CH_NOT_AVBLE:73,REVERT_CH:75,QUICK_SHUTOFF:77,UPN_MSB:78,UPN_MSB_1:79,UPN_MSB_2:80,UPN_LSB:81,CHKSUM_ERROR:82,HANDSHK_TIME:83,PERMANENT_BLK:84,V_MUTE_TIME:86,REAR_RGB_EN:87,EN_NOISE_MUTE:88,KEY_LOCK:90,HDMI2_ENABLE:91,HDMI3_ENABLE:92,RJP_AVAILABLE:93,SAP_MENU_EN:94,DEF_ASP_RATIO:96,AUDIO_OUTPUT:97,PROCENTRIC:98,BACK_LIGHTING:99,VIDEO_INTERFACE:100,IR_FEEDBACK:101,ATSC_BAND:102,ATSC_TUNE_MODE:103,START_MINOR_CH:104,VID_OUT_FORMAT:105,ASP_RATIO_LOCK:106,BANNER_SELECT:107,PANEL_COM:108,PANEL_HNDSHAKE:109,PANEL_DELAY:110,PANEL_VOL_PRE:111,PANEL_STRT_VOL:112,PANEL_TYPE:113,PANEL_MIN_VOL:114,PANEL_MAX_VOL:115,VIDEO_MUTE_EN:116,FACT_DEFAULT:117,POWER_SAVINGS:118,DATA_CHANNEL:119,UPDATE_TIME_HR:121,UPDATE_TIME_MN:122};hcap.property.getInstallerMenuItem=function(r){l("get_installer_menu_item",r)};hcap.property.setInstallerMenuItem=function(r){l("set_installer_menu_item",r)};hcap.Media=function(){};hcap.Media.startUp=function(r){l("media_startup",r)};hcap.Media.shutDown=function(r){l("media_shutdown",r)};hcap.Media.createMedia=function(r){if(r===null){return a}if(a===null&&r.url!==null&&r.mimeType!==null){a=new hcap.Media();l("media_create_media",r);return a}return null};hcap.Media.prototype.play=function(r){if(a===null){r.onFailure({errorMessage:"already destroyed."});return}l("media_play",r)};hcap.Media.prototype.pause=function(r){if(a===null){r.onFailure({errorMessage:"already destroyed."});return}l("media_pause",r)};hcap.Media.prototype.resume=function(r){if(a===null){r.onFailure({errorMessage:"already destroyed."});return}l("media_resume",r)};hcap.Media.prototype.stop=function(r){if(a===null){r.onFailure({errorMessage:"already destroyed."});return}l("media_stop",r)};hcap.Media.prototype.destroy=function(r){if(a===null){r.onFailure({errorMessage:"already destroyed."});return}l("media_destroy",r);a=null};hcap.Media.prototype.getInformation=function(r){if(a===null){r.onFailure({errorMessage:"already destroyed."});return}l("media_get_information",r)};hcap.Media.prototype.getPlayPosition=function(r){if(a===null){r.onFailure({errorMessage:"already destroyed."});return}l("media_get_play_position",r)};hcap.Media.prototype.setPlayPosition=function(r){if(a===null){r.onFailure({errorMessage:"already destroyed."});return}l("media_set_play_position",r)};hcap.Media.prototype.getPlaySpeed=function(r){if(a===null){r.onFailure({errorMessage:"already destroyed."});return}l("media_get_play_speed",r)};hcap.Media.prototype.setPlaySpeed=function(r){if(a===null){r.onFailure({errorMessage:"already destroyed."});return}l("media_set_play_speed",r)};hcap.Media.prototype.setSubtitleOn=function(r){if(a===null){r.onFailure({errorMessage:"already destroyed."});return}l("media_set_subtitle_on",r)};hcap.Media.prototype.getSubtitleOn=function(r){if(a===null){r.onFailure({errorMessage:"already destroyed."});return}l("media_get_subtitle_on",r)};hcap.Media.prototype.setSubtitleUrl=function(r){if(a===null){r.onFailure({errorMessage:"already destroyed."});return}l("media_set_subtitle_url",r)};hcap.Media.prototype.getState=function(r){if(a===null){r.onFailure({errorMessage:"already destroyed."});return}l("media_get_state",r)};hcap.Media.prototype.getAudioLanguage=function(r){l("media_get_audio_language",r)};hcap.Media.prototype.setAudioLanguage=function(r){l("media_set_audio_language",r)};hcap.Media.prototype.getSubtitle=function(r){if(a===null){r.onFailure({errorMessage:"already destroyed."});return}l("media_get_subtitle",r)};hcap.Media.prototype.setSubtitle=function(r){if(a===null){r.onFailure({errorMessage:"already destroyed."});return}l("media_set_subtitle",r)};hcap.Media.SubtitleType={NONE:0,INTERNAL_SUBTITLE:1,EXTERNAL_SUBTITLE:2,CLOSED_CAPTION:3};hcap.rms={};hcap.rms.requestRms=function(r){l("request_rms",r)};hcap.socket={};hcap.socket.openUdpDaemon=function(r){l("open_udp_daemon",r)};hcap.socket.closeUdpDaemon=function(r){l("close_udp_daemon",r)};hcap.socket.openTcpDaemon=function(r){l("open_tcp_daemon",r)};hcap.socket.closeTcpDaemon=function(r){l("close_tcp_daemon",r)};hcap.socket.sendUdpData=function(r){l("send_udp_data",r)};hcap.drm={};hcap.drm.securemedia={};hcap.drm.securemedia.initialize=function(r){l("secure_media_drm_initialize",r)};hcap.drm.securemedia.unregister=function(r){l("secure_media_drm_unregister",r)};hcap.drm.securemedia.isRegistration=function(r){l("secure_media_drm_is_registration",r)};hcap.drm.securemedia.register=function(r){l("secure_media_drm_register",r)};hcap.drm.securemedia.finalize=function(r){l("secure_media_drm_finalize",r)};hcap.file={};hcap.file.getUsbStorageList=function(r){l("get_usb_storage_list",r)};hcap.file.getUsbStorageFileList=function(r){l("get_usb_storage_file_list",r)};hcap.file.downloadFileToUsb=function(r){l("download_file_to_usb",r)};hcap.file.deleteUsbFile=function(r){l("delete_usb_file",r)};hcap.rs232c={};hcap.rs232c.BaudRate={BR_UNKNOWN:0,BR_110:110,BR_300:300,BR_600:600,BR_1200:1200,BR_2400:2400,BR_4800:4800,BR_9600:9600,BR_14400:14400,BR_19200:19200,BR_38400:38400,BR_57600:57600,BR_115200:115200,BR_128000:128000,BR_230400:230400,BR_256000:256000,BR_512000:512000,BR_768000:768000,BR_921600:921600,BR_1024000:1024000};hcap.rs232c.DataBit={BIT_UNKNOWN:0,BIT_7:7,BIT_8:8};hcap.rs232c.Parity={UNKNOWN:0,NONE:1,EVEN:2,ODD:3};hcap.rs232c.StopBit={UNKNOWN:0,BIT_1:1,BIT_2:2};hcap.rs232c.FlowControl={UNKNOWN:0,NONE:1,XON_XOFF:2,HARDWARE:3};hcap.rs232c.getConfiguration=function(r){l("rs232c_get_configuration",r)};hcap.rs232c.setConfiguration=function(r){l("rs232c_set_configuration",r)};hcap.rs232c.sendData=function(r){l("rs232c_send_data",r)};hcap.rs232c.setStartupData=function(r){l("rs232c_set_teaching_data",r)};hcap.rs232c.clearStartupData=function(r){l("rs232c_clear_teaching_data",r)};hcap.system={};hcap.system.requestScreenCaptureImage=function(r){l("request_screen_capture_image",r)};hcap.system.getScreenCaptureImage=function(r){l("get_screen_capture_image",r)};hcap.system.launchHcapHtmlApplication=function(r){l("launch_hcap_html_application",r)};hcap.system.getMemoryUsage=function(r){l("get_memory_usage",r)};hcap.system.getCpuUsage=function(r){l("get_cpu_usage",r)};hcap.system.requestFocus=function(r){l("request_focus",r)};hcap.system.getFocused=function(r){l("get_focused",r)};hcap.system.requestCloning=function(r){l("request_cloning",r)};hcap.system.getLocaleList=function(r){l("get_locale_list",r)};hcap.system.getLocale=function(r){l("get_locale",r)};hcap.system.requestLocaleChange=function(r){l("request_locale_change",r)};hcap.system.getProcentricServer=function(r){l("get_procentric_server",r)};hcap.system.setProcentricServer=function(r){l("set_procentric_server",r)};hcap.system.SoundOutputType={UNKNOWN:0,INTERNAL_TV_SPEAKER:1,WIRED_HEADPHONES:2,OFF:3,OPTICAL:4,OPTICAL_LGSOUNDSYNC:5,EXTERNAL_ARC:6};hcap.system.getSoundOutput=function(r){l("get_sound_output",r)};hcap.system.getDefaultSoundOutput=function(r){l("get_default_sound_output",r)};hcap.system.setSoundOutput=function(r){l("set_sound_output",r)};hcap.system.setDefaultSoundOutput=function(r){l("set_default_sound_output",r)};hcap.system.beginDestroy=function(r){l("begin_destroy",r)};hcap.system.endDestroy=function(r){l("end_destroy",r)};hcap.system.getAudioPtsOffset=function(r){l("get_audio_pts_offset",r)};hcap.system.setAudioPtsOffset=function(r){l("set_audio_pts_offset",r)};hcap.system.getVideoPtsOffset=function(r){l("get_video_pts_offset",r)};hcap.system.setVideoPtsOffset=function(r){l("set_video_pts_offset",r)};hcap.system.getProxyServer=function(r){l("get_proxy_server",r)};hcap.system.setProxyServer=function(r){l("set_proxy_server",r)};hcap.system.expireProxyServer=function(r){l("expire_proxy_server",r)};hcap.system.getBrowserDebugMode=function(r){l("get_browser_debug_mode",r)};hcap.system.setBrowserDebugMode=function(r){l("set_browser_debug_mode",r)};hcap.system.getNoSignalImage=function(r){l("get_no_signal_image",r)};hcap.system.setNoSignalImage=function(r){l("set_no_signal_image",r)};hcap.system.getScreenKeyboardLanguageList=function(r){l("get_screen_keyboard_language_list",r)};hcap.system.setScreenKeyboardLanguage=function(r){l("set_screen_keyboard_language",r)};hcap.system.getUsbPowerControl=function(r){l("get_usb_power_control",r)};hcap.system.setUsbPowerControl=function(r){l("set_usb_power_control",r)};hcap.system.showToastMessage=function(r){l("show_toast_message",r)};hcap.system.startManualUpdate=function(r){l("start_manual_update",r)};hcap.system.cancelUpdate=function(r){l("cancel_update",r)};hcap.system.getUpdateProgress=function(r){l("get_update_progress",r)};hcap.checkout={};hcap.checkout.requestCheckout=function(r){l("request_checkout",r)};hcap.checkout.takeCheckoutSnapshot=function(r){l("take_checkout_snapshot",r)};hcap.beacon={};hcap.beacon.setBeaconMode=function(r){l("set_beacon_mode",r)};hcap.beacon.requestiBeacon=function(r){l("request_iBeacon",r)};hcap.beacon.requestEddystoneUid=function(r){l("request_eddystone_uid",r)};hcap.beacon.requestEddystoneUrl=function(r){l("request_eddystone_url",r)};hcap.beacon.getBeaconInformation=function(r){l("get_beacon_information",r)};hcap.beacon.startScan=function(r){l("beacon_start_scan",r)};hcap.beacon.stopScan=function(r){l("beacon_stop_scan",r)};hcap.bluetooth={};hcap.bluetooth.setScanState=function(r){l("bt_gap_set_scan_state",r)};hcap.bluetooth.disconnect=function(r){l("bt_service_disconnect",r)};hcap.bluetooth.setBluetoothSoundSync=function(r){l("set_bt_sound_sync",r)};hcap.bluetooth.getBluetoothSoundSync=function(r){l("get_bt_sound_sync",r)};hcap.bluetooth.audio={};hcap.bluetooth.audio.play=function(r){l("bt_audio_play",r)};hcap.bluetooth.audio.stop=function(r){l("bt_audio_stop",r)};hcap.bluetooth.audio.pause=function(r){l("bt_audio_pause",r)};hcap.bluetooth.audio.forward=function(r){l("bt_audio_forward",r)};hcap.bluetooth.audio.backward=function(r){l("bt_audio_backward",r)};hcap.webrtc={};hcap.webrtc.startPreviewVideo=function(r){l("webrtc_start_preview_video",r)};hcap.webrtc.stopPreviewVideo=function(r){l("webrtc_stop_preview_video",r)};hcap.webrtc.incomingCall=function(r){l("webrtc_incoming_call",r)};hcap.webrtc.outgoingCall=function(r){l("webrtc_outgoing_call",r)};hcap.webrtc.endCall=function(r){l("webrtc_end_call",r)};hcap.webrtc.acceptMessage=function(r){l("webrtc_accept_message",r)};hcap.webrtc.startCheckAudio=function(r){l("webrtc_start_check_audio",r)};hcap.webrtc.stopCheckAudio=function(r){l("webrtc_stop_check_audio",r)};hcap.webrtc.setConfiguration=function(r){l("webrtc_set_configuration",r)};hcap.webrtc.getConfiguration=function(r){l("webrtc_get_configuration",r)};hcap.webrtc.showDiagnostics=function(r){l("webrtc_show_diagnostics",r)};hcap.security={};hcap.security.registerServerCertificate=function(r){l("register_server_certificate",r)};hcap.security.registerClientCertificate=function(r){l("register_client_certificate",r)};hcap.security.unregisterServerCertificate=function(r){l("unregister_server_certificate",r)};hcap.security.unregisterClientCertificate=function(r){l("unregister_client_certificate",r)};hcap.security.existServerCertificate=function(r){l("exist_server_certificate",r)};hcap.security.existClientCertificate=function(r){l("exist_client_certificate",r)};hcap.iot={};hcap.iot.requestSetBridgeStatus=function(r){l("iot_request_set_bridge_status",r)};hcap.iot.getBridgeStatus=function(r){l("iot_get_bridge_status",r)};hcap.iot.requestRegisterThing=function(r){l("iot_request_register_thing",r)};hcap.iot.requestRejectThing=function(r){l("iot_request_reject_thing",r)};hcap.iot.getThingList=function(r){l("iot_get_thing_list",r)};hcap.iot.getBindingIdList=function(r){l("iot_get_binding_id_list",r)};hcap.iot.requestSetComponent=function(r){l("iot_request_set_component",r)};hcap.iot.requestUnregisterThing=function(r){l("iot_request_unregister_thing",r)};hcap.iot.setThingNickname=function(r){l("iot_set_thing_nickname",r)};hcap.iot.requestSynchronizeThing=function(r){l("iot_request_synchronize_thing",r)};hcap.iot.getFrameworkStatus=function(r){l("iot_get_framework_status",r)};hcap.iot.requestFactoryReset=function(r){l("iot_request_factory_reset",r)};hcap.iot.getVersions=function(r){l("iot_get_versions",r)};hcap.iot.getThingListPrivate=function(r){l("iot_get_thing_list_private",r)};hcap.camera={};hcap.camera.getCameraInformation=function(r){l("get_camera_information",r)};hcap.camera.getCameraControl=function(r){l("get_camera_control",r)};hcap.camera.setCameraControl=function(r){l("set_camera_control",r)};hcap.speech={};hcap.speech.setSpeechRecognition=function(r){l("set_speech_recognition",r)};hcap.speech.getSpeechRecognition=function(r){l("get_speech_recognition",r)};hcap.speech.HostType={NOT_SUPPORT:0,APPLICATION:1,TV:2};hcap.speech.decideHost=function(r){l("decide_host",r)}}())};
\ No newline at end of file
diff --git a/procentric/application/lib/hcap.js.v1.23 b/procentric/application/lib/hcap.js.v1.23
new file mode 100755
index 0000000..7388428
--- /dev/null
+++ b/procentric/application/lib/hcap.js.v1.23
@@ -0,0 +1,9 @@
+/*!
+ * ============================================================================
+ * Creative Innovation Center, LG ELECTRONICS INC., SEOUL, KOREA
+ * Copyright(c) 2018 by LG Electronics Inc.
+ *
+ * Release Version : 1.23.0.5725
+ * ============================================================================
+ */
+var extHcapSecure;var extRegisterHcapCloseHandler;var extDisableHcapConsoleLog;var extWebWorker;var hcap;if(hcap===undefined){(function(){hcap={API_VERSION:"1.23.0.5725"};var g=[],e=0,i=[{command_id:"0",param_text:'{"command_id" : "0", "command" : "notify_sdk_version", "hcap_js_extension_version" : "1.23.0.5725"}'}],k=null,o=false,d=false,n=false,c=null,f=null,l=null,b=false,m=null,a=null;function j(r){if(extDisableHcapConsoleLog!==true){var t;if(r.length>1024){t=r.substring(0,1024)}else{t=r}if(extWebWorker!==true){console.log(t)}}}if(extDisableHcapConsoleLog===true){if(extWebWorker!==true){console.log("hcap console log is disabled")}}else{if(extWebWorker!==true){console.log("hcap console log is enabled")}}j("check external value : extDisableHcapConsoleLog = "+extDisableHcapConsoleLog+", extHcapSecure = "+extHcapSecure+", extRegisterHcapCloseHandler = "+extRegisterHcapCloseHandler);function p(){var r=navigator.userAgent,t=r.match(/Windows/),s=r.match(/Macintosh/),u=r.match(/Mac OS X/);j("UA = '"+r+"'");if(t||s||u){j("HCAP websocket off");return true}return false}b=p();function h(r,x,s,y){var v="",t="",u="";u=x[r];try{v=s[u];t=typeof v}catch(w){v="";t="unknown"}if(t==="function"){v="{/*function*/}"}else{if(t==="object"){v=m("",v)}else{if(t==="string"){v='"'+v+'"'}}}y+='"'+u+'" : '+v;if(r0&&i[0].command_id===s){j(m("command_id = "+s+" received, ",w));if(u){if(i[0].onSuccess){try{i[0].onSuccess(w)}catch(t){j(m("exception : onSuccess : "+t))}}}else{if(i[0].onFailure){try{i[0].onFailure(w)}catch(t){j(m("exception : onFailure : "+t))}}}i.splice(0,1);n=false;f()}else{j(m("invalid response from server ",w));n=false;f()}}};k.onclose=function(){j("websocket : onclose");d=false;o=false;n=false;setTimeout(f,50)};if(extRegisterHcapCloseHandler==="onbeforeunload"){window.onbeforeunload=function(){j("close hcap websocket in onbeforeunload handler");k.onclose=function(){return undefined};k.close()}}else{if(extRegisterHcapCloseHandler==="onunload"){window.onunload=function(){j("close hcap websocket in onunload handler");k.onclose=function(){return undefined};k.close()}}}};f=function(){if(n){return}n=true;if(o){if(i.length>0){j(m("command_id = "+i[0].command_id+" sent, ",JSON.parse(i[0].param_text)));k.send(i[0].param_text);return}}else{c()}n=false};l=function(u,t){if(u===null||u===""||u===undefined){j('[ERROR] command should not null or empty string! command === null || command === "" || command === undefined');return}if(Object.prototype.toString.call(t)==="[object Array]"){j("[ERROR] param should be Object type({})! param is Array. command = "+u);return}if(t===null||t===undefined){j("[ERROR] param should be Object type({})! param === null || param === undefined. command = "+u);return}if(b){if(t.onFailure){t.onFailure({errorMessage:"HCAP WebSocket is not available in this browser"})}return}if(e>1024){e=0}else{e+=1}var r=e.toString(),s="";t.command_id=r;t.command=u;s=JSON.stringify(t,null);i[i.length]={command_id:r,param_text:s,onSuccess:t.onSuccess,onFailure:t.onFailure};j(m("command_id = "+r+" added, ",i[i.length-1]));f()};if(!b){setTimeout(f,200)}hcap.preloadedApplication={};hcap.preloadedApplication.getPreloadedApplicationList=function(r){l("get_preloaded_application_list",r)};hcap.preloadedApplication.launchPreloadedApplication=function(r){l("launch_preloaded_application",r)};hcap.preloadedApplication.destroyPreloadedApplication=function(r){l("destroy_preloaded_application",r)};hcap.application={};hcap.application.getServiceXml=function(r){l("get_service_xml",r)};hcap.application.getDefaultServiceXml=function(r){l("get_default_service_xml",r)};hcap.application.getApplicationList=function(r){l("get_application_list",r)};hcap.application.launchApplication=function(r){l("launch_application",r)};hcap.application.destroyApplication=function(r){l("destroy_application",r)};hcap.video={};hcap.video.getVideoSize=function(r){l("get_video_size",r)};hcap.video.setVideoSize=function(r){l("set_video_size",r)};hcap.video.getOsdTransparencyLevel=function(r){l("get_osd_transparency_level",r)};hcap.video.setOsdTransparencyLevel=function(r){l("set_osd_transparency_level",r)};hcap.video.isVideoMute=function(r){l("get_video_mute",r)};hcap.video.setVideoMute=function(r){l("set_video_mute",r)};hcap.volume={};hcap.volume.getVolumeLevel=function(r){l("get_volume_level",r)};hcap.volume.setVolumeLevel=function(r){l("set_volume_level",r)};hcap.volume.getExternalSpeakerVolumeLevel=function(r){l("get_external_speaker_volume_level",r)};hcap.volume.setExternalSpeakerVolumeLevel=function(r){l("set_external_speaker_volume_level",r)};hcap.volume.getHeadphoneVolumeLevel=function(r){l("get_headphone_volume_level",r)};hcap.volume.setHeadphoneVolumeLevel=function(r){l("set_headphone_volume_level",r)};hcap.volume.setHealthcareHeadphoneMode=function(r){l("set_healthcare_headphone_mode",r)};hcap.volume.getHealthcareHeadphoneMode=function(r){l("get_healthcare_headphone_mode",r)};hcap.channel={};hcap.channel.NO_STREAM_PID=8191;hcap.channel.ChannelType={UNKNOWN:0,RF:1,IP:2,RF_DATA:3,IP_DATA:4};hcap.channel.Polarization={UNKNOWN:0,VERTICAL:1,HORIZONTAL:2,LEFT_HAND_CIRCULAR:3,RIGHT_HAND_CIRCULAR:4};hcap.channel.RfBroadcastType={UNKNOWN:0,TERRESTRIAL:16,TERRESTRIAL_2:17,SATELLITE:32,SATELLITE_2:33,CABLE:48,CABLE_STD:49,CABLE_HRC:50,CABLE_IRC:51,ANALOG_PAL_BG:64,ANALOG_PAL_DK:65,ANALOG_PAL_I:66,ANALOG_PAL_M:67,ANALOG_PAL_N:68,ANALOG_SECAM_BG:69,ANALOG_SECAM_DK:70,ANALOG_SECAM_L:71,ANALOG_NTSC:72,TERRESTRIAL_ATSC3:80,CABLE_ATSC3:81};hcap.channel.IpBroadcastType={UNKNOWN:0,UDP:16,RTP:32};hcap.channel.VideoStreamType={MPEG1:1,MPEG2:2,MPEG4_VISUAL:16,MPEG4_AVC_H264:27,HEVC:36,AVS:66};hcap.channel.AudioStreamType={MPEG1:3,MPEG2:4,MPEG2_AAC:15,MPEG4_HEAAC:17,AC3:129,EAC3:130,ANALOG_BG:256,ANALOG_I:257,ANALOG_DK:258,ANALOG_L:259,ANALOG_MN:260,ANALOG_LP:261,ANALOG_END:262};hcap.channel.InbandDataServiceType={UNKNOWN:0,MHP:1,MHEG:2,HBBTV:3,NONE:4};hcap.channel.ChannelStatus={UNKNOWN:0,AUDIO_VIDEO_NOT_BLOCKED:16,AV_DISPLAYED:16,AUDIO_VIDEO_BLOCKED:33,NO_SIGNAL:33,AUDIO_ONLY_BLOCKED:34,VIDEO_ONLY_BLOCKED:35};hcap.channel.requestChangeCurrentChannel=function(r){l("request_channel_change",r)};hcap.channel.getCurrentChannel=function(r){l("get_current_channel",r)};hcap.channel.replayCurrentChannel=function(r){l("replay_current_channel",r)};hcap.channel.stopCurrentChannel=function(r){l("stop_current_channel",r)};hcap.channel.getDataChannel=function(r){l("get_data_channel",r)};hcap.channel.getStartChannel=function(r){l("get_start_channel",r)};hcap.channel.setStartChannel=function(r){l("set_start_channel",r)};hcap.channel.getCurrentChannelAudioLanguageList=function(r){l("get_current_channel_audio_language_list",r)};hcap.channel.getCurrentChannelAudioLanguageIndex=function(r){l("get_current_channel_audio_language_index",r)};hcap.channel.setCurrentChannelAudioLanguageIndex=function(r){l("set_current_channel_audio_language_index",r)};hcap.channel.getCurrentChannelSubtitleList=function(r){l("get_current_channel_subtitle_language_list",r)};hcap.channel.getCurrentChannelSubtitleIndex=function(r){l("get_current_channel_subtitle_language_index",r)};hcap.channel.setCurrentChannelSubtitleIndex=function(r){l("set_current_channel_subtitle_language_index",r)};hcap.channel.getProgramInfo=function(r){l("get_program_info",r)};hcap.channel.launchInbandDataService=function(r){l("launch_inband_data_service",r)};hcap.channel.getReadyInbandDataService=function(r){l("get_ready_inband_data_service",r)};hcap.channel.getChannelSignalStatus=function(r){l("get_channel_signal_status",r)};hcap.externalinput={};hcap.externalinput.ExternalInputType={TV:1,COMPOSITE:2,SVIDEO:3,COMPONENT:4,RGB:5,HDMI:6,SCART:7,USB:8,OTHERS:9};hcap.externalinput.getCurrentExternalInput=function(r){l("get_external_input",r)};hcap.externalinput.setCurrentExternalInput=function(r){l("set_external_input",r)};hcap.externalinput.isExternalInputConnected=function(r){l("check_external_input_connected",r)};hcap.externalinput.getExternalInputList=function(r){l("get_external_input_list",r)};hcap.carousel={};hcap.carousel.requestCacheCarouselData=function(r){l("request_content",r)};hcap.carousel.isCarouselDataCached=function(r){l("is_content_loaded",r)};hcap.carousel.clearCarouselDataCache=function(r){l("clear_content_cache",r)};hcap.mpi={};hcap.mpi.sendAndReceiveMpiData=function(r){l("send_and_receive_mpi_data",r)};hcap.mpi.sendMpiData=function(r){l("send_mpi_data",r)};hcap.power={};hcap.power.PowerMode={WARM:2,NORMAL:1};hcap.power.getPowerMode=function(r){l("get_power_mode",r)};hcap.power.setPowerMode=function(r){l("set_power_mode",r)};hcap.power.isWarmUpdate=function(r){l("is_power_warm_update",r)};hcap.power.powerOff=function(r){l("power_off",r)};hcap.power.reboot=function(r){l("reboot",r)};hcap.time={};hcap.time.setLocalTime=function(r){l("set_tv_localtime",r)};hcap.time.getLocalTime=function(r){l("get_tv_localtime",r)};hcap.time.getPowerOffTimer=function(r){l("get_power_off_timer_in_min",r)};hcap.time.setPowerOffTimer=function(r){l("set_power_off_timer_in_min",r)};hcap.time.getPowerOnTime=function(r){l("get_power_on_time",r)};hcap.time.setPowerOnTime=function(r){l("set_power_on_time",r)};hcap.time.getAlarmInformation=function(r){l("get_alarm_information",r)};hcap.time.setAlarmInformation=function(r){l("set_alarm_information",r)};hcap.time.getCpuTime=function(r){l("get_cpu_time",r)};hcap.network={};hcap.network.getNumberOfNetworkDevices=function(r){l("get_number_of_network_devices",r)};hcap.network.getNetworkDevice=function(r){l("get_network_device",r)};hcap.network.setNetworkDevice=function(r){l("set_network_device",r)};hcap.network.ping=function(r){l("ping",r)};hcap.network.NetworkEventType={UNKNOWN:0,ETHERNET_PLUGGED:1,ETHERNET_UNPLUGGED:2,WIFI_DONGLE_PLUGGED:3,WIFI_DONGLE_UNPLUGGED:4,IP_CONFLICT:5,IP_NOT_CONFLICT:6,DHCP_SUCCESS:7,DHCP_FAIL:8,UNABLE_REACH_GATEWAY:9,ABLE_REACH_GATEWAY:10,UNABLE_REACH_DNS:11,ABLE_REACH_DNS:12,UNABLE_REACH_INTERNET:13,ABLE_REACH_INTERNET:14,WIFI_AP_SEARCH_COMPLETE:15,WIFI_CONNECTED:16,WIFI_CONNECT_FAIL:17,WIFI_LINK_DROPPED:18};hcap.network.NetworkMode={UNKNOWN:0,WIRE:1,WIRELESS:2,NOT_REACHABLE:3};hcap.network.WirelessMode={UNKNOWN:0,INFRA:1,ADHOC:2};hcap.network.WifiSecurityType={UNKNOWN:0,OPEN:1,WEP:2,WPA_PSK_TKIP:3,WPA_PSK_AES:4,WPA2_PSK_TKIP:5,WPA2_PSK_AES:6,WPA12_PSK_AES_TKIPAES:7};hcap.network.DhcpState={UNKNOWN:0,INIT:1,SELECTING:2,REQUESTING:3,BOUND:4,RENEWING:5,REBINDING:6,INIT_REBOOT:7,REBOOTING:8};hcap.network.getNetworkInformation=function(r){l("get_network_information",r)};hcap.network.getSoftAP=function(r){l("get_soft_ap",r)};hcap.network.setSoftAP=function(r){l("set_soft_ap",r)};hcap.network.getWifiDiagnostics=function(r){l("get_wifi_diagnostics",r)};hcap.network.asyncPing=function(r){l("async_ping",r)};hcap.network.setVlanIdMode=function(r){l("set_vlan_id_mode",r)};hcap.network.getVlanIdMode=function(r){l("get_vlan_id_mode",r)};hcap.network.getLanId=function(r){l("get_lan_id",r)};hcap.network.setLanId=function(r){l("set_lan_id",r)};hcap.network.getAuxLanId=function(r){l("get_aux_lan_id",r)};hcap.network.setAuxLanId=function(r){l("set_aux_lan_id",r)};hcap.mode={};hcap.mode.HCAP_MODE_0=257;hcap.mode.HCAP_MODE_1=258;hcap.mode.HCAP_MODE_2=259;hcap.mode.HCAP_MODE_3=260;hcap.mode.HCAP_MODE_4=261;hcap.mode.getHcapMode=function(r){l("get_mw_mode",r)};hcap.mode.setHcapMode=function(r){l("set_mw_mode",r)};hcap.key={};hcap.key.Code={NUM_0:48,NUM_1:49,NUM_2:50,NUM_3:51,NUM_4:52,NUM_5:53,NUM_6:54,NUM_7:55,NUM_8:56,NUM_9:57,CH_UP:427,CH_DOWN:428,GUIDE:458,INFO:457,LEFT:37,UP:38,RIGHT:39,DOWN:40,ENTER:13,BACK:461,EXIT:1001,RED:403,GREEN:404,YELLOW:405,BLUE:406,STOP:413,PLAY:415,PAUSE:19,REWIND:412,FAST_FORWARD:417,LAST_CH:711,PORTAL:602,ORDER:623,MINUS:704,POWER:409,VOL_UP:447,VOL_DOWN:448,MUTE:449,RECORD:416,PAGE_UP:33,PAGE_DOWN:34,RF_BYPASS:29,NEXT_DAY:425,PREV_DAY:424,APPS:93,LINK:606,FORWARD:167,ZOOM:251,SETTINGS:611,NEXT_FAV_CH:176,RES_1:112,RES_2:113,RES_3:114,RES_4:115,RES_5:116,RES_6:117,LOCK:619,SKIP:620,LIST:1006,LIVE:622,ON_DEMAND:623,PINP_MOVE:624,PINP_UP:625,PINP_DOWN:626,MENU:18,AD:700,ALARM:701,AV_MODE:31,SUBTITLE:460,CC:1008,DISC_POWER_OFF:705,DISC_POWER_ON:706,DVD:707,EJECT:414,ENERGY_SAVING:709,FAV:710,FLASHBK:711,INPUT:712,MARK:713,NETCAST:1000,PIP:715,PIP_CH_DOWN:716,PIP_CH_UP:717,PIP_INPUT:718,PIP_SWAP:719,Q_MENU:1002,Q_VIEW:1007,RATIO:1005,SAP:723,SIMPLINK:724,STB:725,T_OPT:1004,TEXT:459,SLEEP_TIMER:729,TV:730,TV_RAD:731,VCR:732,POWER_LOWBATTERY:733,SMART_HOME:734,SCREEN_REMOTE:735,POINTER:736,LG_3D:737,DATA:738};g[hcap.key.Code.NUM_0]=hcap.key.Code.NUM_0;g[hcap.key.Code.NUM_1]=hcap.key.Code.NUM_1;g[hcap.key.Code.NUM_2]=hcap.key.Code.NUM_2;g[hcap.key.Code.NUM_3]=hcap.key.Code.NUM_3;g[hcap.key.Code.NUM_4]=hcap.key.Code.NUM_4;g[hcap.key.Code.NUM_5]=hcap.key.Code.NUM_5;g[hcap.key.Code.NUM_6]=hcap.key.Code.NUM_6;g[hcap.key.Code.NUM_7]=hcap.key.Code.NUM_7;g[hcap.key.Code.NUM_8]=hcap.key.Code.NUM_8;g[hcap.key.Code.NUM_9]=hcap.key.Code.NUM_9;g[hcap.key.Code.CH_UP]=hcap.key.Code.CH_UP;g[hcap.key.Code.CH_DOWN]=hcap.key.Code.CH_DOWN;g[hcap.key.Code.GUIDE]=hcap.key.Code.GUIDE;g[hcap.key.Code.INFO]=hcap.key.Code.INFO;g[hcap.key.Code.LEFT]=hcap.key.Code.LEFT;g[hcap.key.Code.UP]=hcap.key.Code.UP;g[hcap.key.Code.RIGHT]=hcap.key.Code.RIGHT;g[hcap.key.Code.DOWN]=hcap.key.Code.DOWN;g[hcap.key.Code.ENTER]=10;g[hcap.key.Code.BACK]=608;g[hcap.key.Code.EXIT]=601;g[hcap.key.Code.RED]=hcap.key.Code.RED;g[hcap.key.Code.GREEN]=hcap.key.Code.GREEN;g[hcap.key.Code.YELLOW]=hcap.key.Code.YELLOW;g[hcap.key.Code.BLUE]=hcap.key.Code.BLUE;g[hcap.key.Code.STOP]=hcap.key.Code.STOP;g[hcap.key.Code.PLAY]=hcap.key.Code.PLAY;g[hcap.key.Code.PAUSE]=hcap.key.Code.PAUSE;g[hcap.key.Code.REWIND]=hcap.key.Code.REWIND;g[hcap.key.Code.FAST_FORWARD]=hcap.key.Code.FAST_FORWARD;g[hcap.key.Code.LAST_CH]=607;g[hcap.key.Code.PORTAL]=hcap.key.Code.PORTAL;g[hcap.key.Code.ORDER]=hcap.key.Code.ORDER;g[hcap.key.Code.MINUS]=45;g[hcap.key.Code.POWER]=hcap.key.Code.POWER;g[hcap.key.Code.VOL_UP]=hcap.key.Code.VOL_UP;g[hcap.key.Code.VOL_DOWN]=hcap.key.Code.VOL_DOWN;g[hcap.key.Code.MUTE]=hcap.key.Code.MUTE;g[hcap.key.Code.RECORD]=hcap.key.Code.RECORD;g[hcap.key.Code.PAGE_UP]=hcap.key.Code.PAGE_UP;g[hcap.key.Code.PAGE_DOWN]=hcap.key.Code.PAGE_DOWN;g[hcap.key.Code.RF_BYPASS]=600;g[hcap.key.Code.NEXT_DAY]=603;g[hcap.key.Code.PREV_DAY]=604;g[hcap.key.Code.APPS]=605;g[hcap.key.Code.LINK]=hcap.key.Code.LINK;g[hcap.key.Code.FORWARD]=609;g[hcap.key.Code.ZOOM]=610;g[hcap.key.Code.SETTINGS]=hcap.key.Code.SETTINGS;g[hcap.key.Code.NEXT_FAV_CH]=612;g[hcap.key.Code.RES_1]=613;g[hcap.key.Code.RES_2]=614;g[hcap.key.Code.RES_3]=615;g[hcap.key.Code.RES_4]=616;g[hcap.key.Code.RES_5]=617;g[hcap.key.Code.RES_6]=618;g[hcap.key.Code.LOCK]=hcap.key.Code.LOCK;g[hcap.key.Code.SKIP]=hcap.key.Code.SKIP;g[hcap.key.Code.LIST]=621;g[hcap.key.Code.LIVE]=hcap.key.Code.LIVE;g[hcap.key.Code.ON_DEMAND]=hcap.key.Code.ON_DEMAND;g[hcap.key.Code.PINP_MOVE]=hcap.key.Code.PINP_MOVE;g[hcap.key.Code.PINP_UP]=hcap.key.Code.PINP_UP;g[hcap.key.Code.PINP_DOWN]=hcap.key.Code.PINP_DOWN;g[hcap.key.Code.MENU]=627;g[hcap.key.Code.AD]=hcap.key.Code.AD;g[hcap.key.Code.ALARM]=hcap.key.Code.ALARM;g[hcap.key.Code.AV_MODE]=702;g[hcap.key.Code.SUBTITLE]=726;g[hcap.key.Code.CC]=726;g[hcap.key.Code.DISC_POWER_OFF]=hcap.key.Code.DISC_POWER_OFF;g[hcap.key.Code.DISC_POWER_ON]=hcap.key.Code.DISC_POWER_ON;g[hcap.key.Code.DVD]=hcap.key.Code.DVD;g[hcap.key.Code.EJECT]=708;g[hcap.key.Code.ENERGY_SAVING]=hcap.key.Code.ENERGY_SAVING;g[hcap.key.Code.FAV]=hcap.key.Code.FAV;g[hcap.key.Code.FLASHBK]=hcap.key.Code.FLASHBK;g[hcap.key.Code.INPUT]=hcap.key.Code.INPUT;g[hcap.key.Code.MARK]=hcap.key.Code.MARK;g[hcap.key.Code.NETCAST]=714;g[hcap.key.Code.PIP]=hcap.key.Code.PIP;g[hcap.key.Code.PIP_CH_DOWN]=hcap.key.Code.PIP_CH_DOWN;g[hcap.key.Code.PIP_CH_UP]=hcap.key.Code.PIP_CH_UP;g[hcap.key.Code.PIP_INPUT]=hcap.key.Code.PIP_INPUT;g[hcap.key.Code.PIP_SWAP]=hcap.key.Code.PIP_SWAP;g[hcap.key.Code.Q_MENU]=720;g[hcap.key.Code.Q_VIEW]=721;g[hcap.key.Code.RATIO]=722;g[hcap.key.Code.SAP]=hcap.key.Code.SAP;g[hcap.key.Code.SIMPLINK]=hcap.key.Code.SIMPLINK;g[hcap.key.Code.STB]=hcap.key.Code.STB;g[hcap.key.Code.T_OPT]=727;g[hcap.key.Code.TEXT]=728;g[hcap.key.Code.SLEEP_TIMER]=hcap.key.Code.SLEEP_TIMER;g[hcap.key.Code.TV]=hcap.key.Code.TV;g[hcap.key.Code.TV_RAD]=hcap.key.Code.TV_RAD;g[hcap.key.Code.VCR]=hcap.key.Code.VCR;g[hcap.key.Code.POWER_LOWBATTERY]=hcap.key.Code.POWER_LOWBATTERY;g[hcap.key.Code.SMART_HOME]=hcap.key.Code.SMART_HOME;g[hcap.key.Code.SCREEN_REMOTE]=hcap.key.Code.SCREEN_REMOTE;g[hcap.key.Code.POINTER]=hcap.key.Code.POINTER;g[hcap.key.Code.LG_3D]=hcap.key.Code.LG_3D;g[hcap.key.Code.DATA]=hcap.key.Code.DATA;hcap.key.addKeyItem=function(r){r.virtualKeycode=g[r.virtualKeycode];l("add_key_item",r)};hcap.key.removeKeyItem=function(r){l("remove_key_item",r)};hcap.key.clearKeyTable=function(r){l("clear_key_table",r)};hcap.key.sendKey=function(r){r.virtualKeycode=g[r.virtualKeycode];l("send_key",r)};hcap.mouse={};hcap.mouse.isMouseVisible=function(r){l("get_mouse_visible",r)};hcap.mouse.setMouseVisible=function(r){l("set_mouse_visible",r)};hcap.mouse.isPointerOn=function(r){l("is_pointer_on",r)};hcap.mouse.setPointerOn=function(r){l("set_pointer_on",r)};hcap.mouse.getPointerPosition=function(r){l("get_pointer_position",r)};hcap.mouse.setPointerPosition=function(r){l("set_pointer_position",r)};hcap.mouse.clickPointer=function(r){l("click_pointer",r)};hcap.mouse.setPointerSize=function(r){l("set_pointer_size",r)};hcap.property={};hcap.property.getHotelMode=function(r){l("get_hotel_mode",r)};hcap.property.setHotelMode=function(r){l("set_hotel_mode",r)};hcap.property.PicturePropertyKey={BACKLIGHT:1,CONTRAST:2,BRIGHTNESS:3,SHARPNESS:4,COLOR:5,TINT:6,COLOR_TEMPERATURE:7,ASPECT_RATIO:8};hcap.property.getPictureProperty=function(r){l("get_picture_property",r)};hcap.property.setPictureProperty=function(r){l("set_picture_property",r)};hcap.property.PictureMode={VIVID:1,STANDARD:2,ECO:3,CINEMA:4,SPORTS:5,GAME:6,PHOTO:7,EXPERT_BRIGHT_ROOM:8,EXPERT_DARK_ROOM:9};hcap.property.getPictureMode=function(r){l("get_picture_mode",r)};hcap.property.setPictureMode=function(r){l("set_picture_mode",r)};hcap.property.getProperty=function(r){l("get_property",r)};hcap.property.setProperty=function(r){l("set_property",r)};hcap.property.InstallerMenuItem={INSTALLER_SEQ:0,POWER_MANAGE:1,AC_ON:2,BAND:3,STRT_CHANNEL:4,CHAN_LOCK:5,STRT_VOLUME:7,MIN_VOLUME:8,MAX_VOLUME:9,MUTE_DISABLE:10,KEY_DEFEAT:11,IR_BANKS_ENABLE:12,SCAN_MODE:13,STRT_CH_IN_SM:14,SLEEP_TIMER:15,EN_TIMER:16,ALARM:17,FEATURE_LEVEL:20,V_CHIP:21,MAX_BLK_HRS:22,CAPTION_LOCK:23,FUNCTION_PRE:25,HOSPITAL_MODE:27,CH_OVERIDE:28,REMAP_AUX_INPS:29,ACK_MASK:30,POLL_RATE:31,TIMING_PULSE:32,COMPORT_EN:34,HDMI1_ENABLE:35,REAR_AUX_EN:39,SIMPLINK_EN:41,AUTO_INPUTS:42,STRT_AUX_SRCE:46,AUX_STATUS:47,DIS_AUDIO_M:49,DIS_CH_TIME:53,EN_CH_T_COL:69,FOR_CH_TIME:70,BCK_CH_TIME:71,CH_NOT_AVBLE:73,REVERT_CH:75,QUICK_SHUTOFF:77,UPN_MSB:78,UPN_MSB_1:79,UPN_MSB_2:80,UPN_LSB:81,CHKSUM_ERROR:82,HANDSHK_TIME:83,PERMANENT_BLK:84,V_MUTE_TIME:86,REAR_RGB_EN:87,EN_NOISE_MUTE:88,KEY_LOCK:90,HDMI2_ENABLE:91,HDMI3_ENABLE:92,RJP_AVAILABLE:93,SAP_MENU_EN:94,DEF_ASP_RATIO:96,AUDIO_OUTPUT:97,PROCENTRIC:98,BACK_LIGHTING:99,VIDEO_INTERFACE:100,IR_FEEDBACK:101,ATSC_BAND:102,ATSC_TUNE_MODE:103,START_MINOR_CH:104,VID_OUT_FORMAT:105,ASP_RATIO_LOCK:106,BANNER_SELECT:107,PANEL_COM:108,PANEL_HNDSHAKE:109,PANEL_DELAY:110,PANEL_VOL_PRE:111,PANEL_STRT_VOL:112,PANEL_TYPE:113,PANEL_MIN_VOL:114,PANEL_MAX_VOL:115,VIDEO_MUTE_EN:116,FACT_DEFAULT:117,POWER_SAVINGS:118,DATA_CHANNEL:119,UPDATE_TIME_HR:121,UPDATE_TIME_MN:122};hcap.property.getInstallerMenuItem=function(r){l("get_installer_menu_item",r)};hcap.property.setInstallerMenuItem=function(r){l("set_installer_menu_item",r)};hcap.Media=function(){};hcap.Media.startUp=function(r){l("media_startup",r)};hcap.Media.shutDown=function(r){l("media_shutdown",r)};hcap.Media.createMedia=function(r){if(r===null){return a}if(a===null&&r.url!==null&&r.mimeType!==null){a=new hcap.Media();l("media_create_media",r);return a}return null};hcap.Media.prototype.play=function(r){if(a===null){r.onFailure({errorMessage:"already destroyed."});return}l("media_play",r)};hcap.Media.prototype.pause=function(r){if(a===null){r.onFailure({errorMessage:"already destroyed."});return}l("media_pause",r)};hcap.Media.prototype.resume=function(r){if(a===null){r.onFailure({errorMessage:"already destroyed."});return}l("media_resume",r)};hcap.Media.prototype.stop=function(r){if(a===null){r.onFailure({errorMessage:"already destroyed."});return}l("media_stop",r)};hcap.Media.prototype.destroy=function(r){if(a===null){r.onFailure({errorMessage:"already destroyed."});return}l("media_destroy",r);a=null};hcap.Media.prototype.getInformation=function(r){if(a===null){r.onFailure({errorMessage:"already destroyed."});return}l("media_get_information",r)};hcap.Media.prototype.getPlayPosition=function(r){if(a===null){r.onFailure({errorMessage:"already destroyed."});return}l("media_get_play_position",r)};hcap.Media.prototype.setPlayPosition=function(r){if(a===null){r.onFailure({errorMessage:"already destroyed."});return}l("media_set_play_position",r)};hcap.Media.prototype.getPlaySpeed=function(r){if(a===null){r.onFailure({errorMessage:"already destroyed."});return}l("media_get_play_speed",r)};hcap.Media.prototype.setPlaySpeed=function(r){if(a===null){r.onFailure({errorMessage:"already destroyed."});return}l("media_set_play_speed",r)};hcap.Media.prototype.setSubtitleOn=function(r){if(a===null){r.onFailure({errorMessage:"already destroyed."});return}l("media_set_subtitle_on",r)};hcap.Media.prototype.getSubtitleOn=function(r){if(a===null){r.onFailure({errorMessage:"already destroyed."});return}l("media_get_subtitle_on",r)};hcap.Media.prototype.setSubtitleUrl=function(r){if(a===null){r.onFailure({errorMessage:"already destroyed."});return}l("media_set_subtitle_url",r)};hcap.Media.prototype.getState=function(r){if(a===null){r.onFailure({errorMessage:"already destroyed."});return}l("media_get_state",r)};hcap.Media.prototype.getAudioLanguage=function(r){l("media_get_audio_language",r)};hcap.Media.prototype.setAudioLanguage=function(r){l("media_set_audio_language",r)};hcap.Media.prototype.getSubtitle=function(r){if(a===null){r.onFailure({errorMessage:"already destroyed."});return}l("media_get_subtitle",r)};hcap.Media.prototype.setSubtitle=function(r){if(a===null){r.onFailure({errorMessage:"already destroyed."});return}l("media_set_subtitle",r)};hcap.Media.SubtitleType={NONE:0,INTERNAL_SUBTITLE:1,EXTERNAL_SUBTITLE:2,CLOSED_CAPTION:3};hcap.rms={};hcap.rms.requestRms=function(r){l("request_rms",r)};hcap.socket={};hcap.socket.openUdpDaemon=function(r){l("open_udp_daemon",r)};hcap.socket.closeUdpDaemon=function(r){l("close_udp_daemon",r)};hcap.socket.openTcpDaemon=function(r){l("open_tcp_daemon",r)};hcap.socket.closeTcpDaemon=function(r){l("close_tcp_daemon",r)};hcap.socket.sendUdpData=function(r){l("send_udp_data",r)};hcap.drm={};hcap.drm.securemedia={};hcap.drm.securemedia.initialize=function(r){l("secure_media_drm_initialize",r)};hcap.drm.securemedia.unregister=function(r){l("secure_media_drm_unregister",r)};hcap.drm.securemedia.isRegistration=function(r){l("secure_media_drm_is_registration",r)};hcap.drm.securemedia.register=function(r){l("secure_media_drm_register",r)};hcap.drm.securemedia.finalize=function(r){l("secure_media_drm_finalize",r)};hcap.file={};hcap.file.getUsbStorageList=function(r){l("get_usb_storage_list",r)};hcap.file.getUsbStorageFileList=function(r){l("get_usb_storage_file_list",r)};hcap.file.downloadFileToUsb=function(r){l("download_file_to_usb",r)};hcap.file.deleteUsbFile=function(r){l("delete_usb_file",r)};hcap.rs232c={};hcap.rs232c.BaudRate={BR_UNKNOWN:0,BR_110:110,BR_300:300,BR_600:600,BR_1200:1200,BR_2400:2400,BR_4800:4800,BR_9600:9600,BR_14400:14400,BR_19200:19200,BR_38400:38400,BR_57600:57600,BR_115200:115200,BR_128000:128000,BR_230400:230400,BR_256000:256000,BR_512000:512000,BR_768000:768000,BR_921600:921600,BR_1024000:1024000};hcap.rs232c.DataBit={BIT_UNKNOWN:0,BIT_7:7,BIT_8:8};hcap.rs232c.Parity={UNKNOWN:0,NONE:1,EVEN:2,ODD:3};hcap.rs232c.StopBit={UNKNOWN:0,BIT_1:1,BIT_2:2};hcap.rs232c.FlowControl={UNKNOWN:0,NONE:1,XON_XOFF:2,HARDWARE:3};hcap.rs232c.getConfiguration=function(r){l("rs232c_get_configuration",r)};hcap.rs232c.setConfiguration=function(r){l("rs232c_set_configuration",r)};hcap.rs232c.sendData=function(r){l("rs232c_send_data",r)};hcap.rs232c.setStartupData=function(r){l("rs232c_set_teaching_data",r)};hcap.rs232c.clearStartupData=function(r){l("rs232c_clear_teaching_data",r)};hcap.system={};hcap.system.requestScreenCaptureImage=function(r){l("request_screen_capture_image",r)};hcap.system.getScreenCaptureImage=function(r){l("get_screen_capture_image",r)};hcap.system.launchHcapHtmlApplication=function(r){l("launch_hcap_html_application",r)};hcap.system.getMemoryUsage=function(r){l("get_memory_usage",r)};hcap.system.getCpuUsage=function(r){l("get_cpu_usage",r)};hcap.system.requestFocus=function(r){l("request_focus",r)};hcap.system.getFocused=function(r){l("get_focused",r)};hcap.system.requestCloning=function(r){l("request_cloning",r)};hcap.system.getLocaleList=function(r){l("get_locale_list",r)};hcap.system.getLocale=function(r){l("get_locale",r)};hcap.system.requestLocaleChange=function(r){l("request_locale_change",r)};hcap.system.getProcentricServer=function(r){l("get_procentric_server",r)};hcap.system.setProcentricServer=function(r){l("set_procentric_server",r)};hcap.system.SoundOutputType={UNKNOWN:0,INTERNAL_TV_SPEAKER:1,WIRED_HEADPHONES:2,OFF:3,OPTICAL:4,OPTICAL_LGSOUNDSYNC:5,EXTERNAL_ARC:6};hcap.system.getSoundOutput=function(r){l("get_sound_output",r)};hcap.system.getDefaultSoundOutput=function(r){l("get_default_sound_output",r)};hcap.system.setSoundOutput=function(r){l("set_sound_output",r)};hcap.system.setDefaultSoundOutput=function(r){l("set_default_sound_output",r)};hcap.system.beginDestroy=function(r){l("begin_destroy",r)};hcap.system.endDestroy=function(r){l("end_destroy",r)};hcap.system.getAudioPtsOffset=function(r){l("get_audio_pts_offset",r)};hcap.system.setAudioPtsOffset=function(r){l("set_audio_pts_offset",r)};hcap.system.getVideoPtsOffset=function(r){l("get_video_pts_offset",r)};hcap.system.setVideoPtsOffset=function(r){l("set_video_pts_offset",r)};hcap.system.getProxyServer=function(r){l("get_proxy_server",r)};hcap.system.setProxyServer=function(r){l("set_proxy_server",r)};hcap.system.expireProxyServer=function(r){l("expire_proxy_server",r)};hcap.system.getBrowserDebugMode=function(r){l("get_browser_debug_mode",r)};hcap.system.setBrowserDebugMode=function(r){l("set_browser_debug_mode",r)};hcap.system.getNoSignalImage=function(r){l("get_no_signal_image",r)};hcap.system.setNoSignalImage=function(r){l("set_no_signal_image",r)};hcap.system.getScreenKeyboardLanguageList=function(r){l("get_screen_keyboard_language_list",r)};hcap.system.setScreenKeyboardLanguage=function(r){l("set_screen_keyboard_language",r)};hcap.system.getUsbPowerControl=function(r){l("get_usb_power_control",r)};hcap.system.setUsbPowerControl=function(r){l("set_usb_power_control",r)};hcap.checkout={};hcap.checkout.requestCheckout=function(r){l("request_checkout",r)};hcap.checkout.takeCheckoutSnapshot=function(r){l("take_checkout_snapshot",r)};hcap.beacon={};hcap.beacon.setBeaconMode=function(r){l("set_beacon_mode",r)};hcap.beacon.requestiBeacon=function(r){l("request_iBeacon",r)};hcap.beacon.requestEddystoneUid=function(r){l("request_eddystone_uid",r)};hcap.beacon.requestEddystoneUrl=function(r){l("request_eddystone_url",r)};hcap.beacon.getBeaconInformation=function(r){l("get_beacon_information",r)};hcap.bluetooth={};hcap.bluetooth.setScanState=function(r){l("bt_gap_set_scan_state",r)};hcap.bluetooth.disconnect=function(r){l("bt_service_disconnect",r)};hcap.bluetooth.setBluetoothSoundSync=function(r){l("set_bt_sound_sync",r)};hcap.bluetooth.getBluetoothSoundSync=function(r){l("get_bt_sound_sync",r)};hcap.bluetooth.audio={};hcap.bluetooth.audio.play=function(r){l("bt_audio_play",r)};hcap.bluetooth.audio.stop=function(r){l("bt_audio_stop",r)};hcap.bluetooth.audio.pause=function(r){l("bt_audio_pause",r)};hcap.bluetooth.audio.forward=function(r){l("bt_audio_forward",r)};hcap.bluetooth.audio.backward=function(r){l("bt_audio_backward",r)};hcap.webrtc={};hcap.webrtc.startPreviewVideo=function(r){l("webrtc_start_preview_video",r)};hcap.webrtc.stopPreviewVideo=function(r){l("webrtc_stop_preview_video",r)};hcap.webrtc.incomingCall=function(r){l("webrtc_incoming_call",r)};hcap.webrtc.outgoingCall=function(r){l("webrtc_outgoing_call",r)};hcap.webrtc.endCall=function(r){l("webrtc_end_call",r)};hcap.webrtc.acceptMessage=function(r){l("webrtc_accept_message",r)};hcap.webrtc.startCheckAudio=function(r){l("webrtc_start_check_audio",r)};hcap.webrtc.stopCheckAudio=function(r){l("webrtc_stop_check_audio",r)};hcap.webrtc.setConfiguration=function(r){l("webrtc_set_configuration",r)};hcap.webrtc.getConfiguration=function(r){l("webrtc_get_configuration",r)};hcap.webrtc.showDiagnostics=function(r){l("webrtc_show_diagnostics",r)};hcap.security={};hcap.security.registerServerCertificate=function(r){l("register_server_certificate",r)};hcap.security.registerClientCertificate=function(r){l("register_client_certificate",r)};hcap.security.unregisterServerCertificate=function(r){l("unregister_server_certificate",r)};hcap.security.unregisterClientCertificate=function(r){l("unregister_client_certificate",r)};hcap.security.existServerCertificate=function(r){l("exist_server_certificate",r)};hcap.security.existClientCertificate=function(r){l("exist_client_certificate",r)};hcap.iot={};hcap.iot.requestSetBridgeStatus=function(r){l("iot_request_set_bridge_status",r)};hcap.iot.getBridgeStatus=function(r){l("iot_get_bridge_status",r)};hcap.iot.requestRegisterThing=function(r){l("iot_request_register_thing",r)};hcap.iot.requestRejectThing=function(r){l("iot_request_reject_thing",r)};hcap.iot.getThingList=function(r){l("iot_get_thing_list",r)};hcap.iot.getBindingIdList=function(r){l("iot_get_binding_id_list",r)};hcap.iot.requestSetComponent=function(r){l("iot_request_set_component",r)};hcap.iot.requestUnregisterThing=function(r){l("iot_request_unregister_thing",r)};hcap.iot.setThingNickname=function(r){l("iot_set_thing_nickname",r)};hcap.iot.requestSynchronizeThing=function(r){l("iot_request_synchronize_thing",r)};hcap.iot.getFrameworkStatus=function(r){l("iot_get_framework_status",r)};hcap.iot.requestFactoryReset=function(r){l("iot_request_factory_reset",r)};hcap.iot.getVersions=function(r){l("iot_get_versions",r)};hcap.iot.getThingListPrivate=function(r){l("iot_get_thing_list_private",r)};hcap.speech={};hcap.speech.setSpeechRecognition=function(r){l("set_speech_recognition",r)};hcap.speech.getSpeechRecognition=function(r){l("get_speech_recognition",r)};hcap.speech.HostType={NOT_SUPPORT:0,APPLICATION:1,TV:2};hcap.speech.decideHost=function(r){l("decide_host",r)}}())};
\ No newline at end of file
diff --git a/procentric/application/lib/hoteltv.api.js b/procentric/application/lib/hoteltv.api.js
new file mode 100755
index 0000000..597411b
--- /dev/null
+++ b/procentric/application/lib/hoteltv.api.js
@@ -0,0 +1,728 @@
+/**
+ * Copyright (c) 2020
+ *
+ * CENTIRM HotelTV HCAP module javascript.
+ *
+ * @summary short description for the file
+ * @author Joel
+ *
+ * Created at : 2020-11-26 02:21:56
+ * Last modified : 2020-11-26 15:31:40
+ */
+
+HotelTV.namespace('HotelTV.api');
+HotelTV.api = (function() {
+ //// 의존 관계 선언
+ let _api_ver = Object.prototype.toString,
+ _svr_ip = Object.prototype.toString,
+ _serial_num = Object.prototype.toString,
+ _dev_familly = Object.prototype.toString,
+ _license = Object.prototype.toString,
+ _token = "aLc*eBgTijklRnopq4s",
+ _registered = false,
+ _exist = false,
+ _svr_port = 0;
+
+ //// 비공개 프로퍼티
+
+ /// 초기화 루틴
+
+ //// 비공개 매써드
+ /**
+ *
+ */
+ function __apifxn_init(param) {
+ _api_ver = param.api_ver;
+ _serial_num = param.serial_num;
+ _svr_ip = param.svr_ip;
+ _svr_port = param.svr_port;
+ _dev_familly = param.dev_familly;
+ _license = param.license;
+ _token = param.apikey;
+ _registered = param.registered;
+ _exist = param.exist;
+ }
+
+
+ /**
+ * API Wrapper Function::> Get API base URI
+ */
+ function __apifxn_get_base_url() {
+ var sz_base_url = "http://" + _svr_ip + ":" + _svr_port;
+ return sz_base_url;
+ }
+
+ /**
+ * API Wrapper Function::> Get Device License
+ */
+ function __apifxn_get_license() {
+ return _license;
+ }
+
+
+ /**
+ * API Wrapper Function::> Get Device Registered
+ */
+ function __apifxn_get_registered() {
+ return { 'registered': _registered, 'exist': _exist, 'license': _license };
+ }
+
+ /**
+ * API Wrapper Function::> Get API Token
+ */
+ function __apifxn_get_token() {
+ return _token;
+ }
+
+
+ /**
+ * API Wrapper Function::> Get ProCentric Server Info(Realted HCAP API:hcap.system.getProcentricServer)
+ */
+ function __apifxn_get_api_url(api_type) {
+ var dic_api_url = {
+ "get_translation": __apifxn_get_base_url() + "/api/" + _api_ver + "/assets/" + _dev_familly + "/" + _serial_num + "/translation",
+ "get_device_settings": __apifxn_get_base_url() + "/api/" + _api_ver + "/assets/" + _dev_familly + "/" + _serial_num + "/setting",
+ "get_site_info": __apifxn_get_base_url() + "/api/" + _api_ver + "/assets/" + _dev_familly + "/" + _serial_num + "/info",
+ "get_guest_info": __apifxn_get_base_url() + "/api/" + _api_ver + "/assets/" + _dev_familly + "/" + _serial_num + "/guest",
+ "get_opening_ctz": __apifxn_get_base_url() + "/api/" + _api_ver + "/assets/" + _dev_familly + "/" + _serial_num + "/opening",
+ "get_program_ctz": __apifxn_get_base_url() + "/api/" + _api_ver + "/assets/" + _dev_familly + "/" + _serial_num + "/program",
+ "get_epg_info": __apifxn_get_base_url() + "/api/" + _api_ver + "/assets/" + _dev_familly + "/" + _serial_num + "/epg",
+ "get_weather": __apifxn_get_base_url() + "/api/" + _api_ver + "/assets/" + _dev_familly + "/" + _serial_num + "/weather",
+ "get_flight": __apifxn_get_base_url() + "/api/" + _api_ver + "/assets/" + _dev_familly + "/" + _serial_num + "/flight",
+ "get_services": __apifxn_get_base_url() + "/api/" + _api_ver + "/assets/" + _dev_familly + "/" + _serial_num + "/services",
+ "get_news": __apifxn_get_base_url() + "/api/" + _api_ver + "/assets/" + _dev_familly + "/" + _serial_num + "/news",
+ "get_message": __apifxn_get_base_url() + "/api/" + _api_ver + "/assets/" + _dev_familly + "/" + _serial_num + "/messages",
+ "get_carts_amenity": __apifxn_get_base_url() + "/api/" + _api_ver + "/assets/" + _dev_familly + "/" + _serial_num + "/requests/amenity/carts",
+ "put_carts_amenity": __apifxn_get_base_url() + "/api/" + _api_ver + "/assets/" + _dev_familly + "/" + _serial_num + "/requests/amenity/carts",
+ "update_carts_amenity": __apifxn_get_base_url() + "/api/" + _api_ver + "/assets/" + _dev_familly + "/" + _serial_num + "/requests/amenity/carts",
+ "delete_carts_amenity": __apifxn_get_base_url() + "/api/" + _api_ver + "/assets/" + _dev_familly + "/" + _serial_num + "/requests/amenity/carts",
+ "get_order_amenity": __apifxn_get_base_url() + "/api/" + _api_ver + "/assets/" + _dev_familly + "/" + _serial_num + "/requests/amenity/orders",
+ "put_order_amenity": __apifxn_get_base_url() + "/api/" + _api_ver + "/assets/" + _dev_familly + "/" + _serial_num + "/requests/amenity/orders",
+ "get_carts_roomservice": __apifxn_get_base_url() + "/api/" + _api_ver + "/assets/" + _dev_familly + "/" + _serial_num + "/requests/roomService/carts",
+ "put_carts_roomservice": __apifxn_get_base_url() + "/api/" + _api_ver + "/assets/" + _dev_familly + "/" + _serial_num + "/requests/roomService/carts",
+ "update_carts_roomservice": __apifxn_get_base_url() + "/api/" + _api_ver + "/assets/" + _dev_familly + "/" + _serial_num + "/requests/roomService/carts",
+ "delete_carts_roomservice": __apifxn_get_base_url() + "/api/" + _api_ver + "/assets/" + _dev_familly + "/" + _serial_num + "/requests/roomService/carts",
+ "get_order_roomservice": __apifxn_get_base_url() + "/api/" + _api_ver + "/assets/" + _dev_familly + "/" + _serial_num + "/requests/roomService/orders",
+ "put_order_roomservice": __apifxn_get_base_url() + "/api/" + _api_ver + "/assets/" + _dev_familly + "/" + _serial_num + "/requests/roomService/orders",
+
+ /*
+ "get_emergency": __apifxn_get_base_url() + "/api/" + _api_ver + "/settops/" + _serial_num + "/emergency",
+ "get_news": __apifxn_get_base_url() + "/api/" + _api_ver + "/settops/" + _serial_num + "/news",
+ "get_message": __apifxn_get_base_url() + "/api/" + _api_ver + "/settops/" + _serial_num + "/messages",
+ "set_message_status": __apifxn_get_base_url() + "/api/" + _api_ver + "/settops/" + _serial_num + "/messages",
+ "set_device_status": __apifxn_get_base_url() + "/api/" + _api_ver + "/settops/" + _serial_num + "/state",
+ "get_epg_info": __apifxn_get_base_url() + "/api/" + _api_ver + "/channels/epg",
+ "set_device_opmode": __apifxn_get_base_url() + "/api/" + _api_ver + "/settops/" + _serial_num + "/bbdoors/opmode",
+ */
+ }
+
+ if (api_type in dic_api_url) {
+ return dic_api_url[api_type];
+ }
+ return null;
+ }
+
+
+ function __apifxn_CallCmsApi(_method, sz_url, api_type, dic_param) {
+ return new Promise((resolve, reject) => {
+ let isPostMsg = false;
+ let xhr = new XMLHttpRequest();
+ // let formData = new FormData();
+ let _ret = { type: api_type, error: true, reason: null, data: null };
+
+ //xhr.timeout = 500;
+ if (dic_param !== null) {
+ isPostMsg = true;
+ // for (_key in dic_param) {
+ // formData.append(_key.toString(), dic_param[_key]);
+ // }
+ }
+
+ xhr.onload = function() {
+ if (xhr.status === 200 || xhr.status === 201) {
+ _ret.error = false;
+ _ret.data = xhr.response;
+ resolve(_ret);
+ } else {
+ reject(_ret);
+ }
+ };
+
+ xhr.ontimeout = function(e) {
+ // XMLHttpRequest timed out. Do something here.
+ _ret.reason = "TIMEOUT";
+ reject(_ret);
+ };
+
+ xhr.onerror = function() {
+ _ret.reason = "FATAL";
+ reject(_ret);
+ }
+
+ switch (_method) {
+ case "GET":
+ xhr.open('GET', sz_url, true);
+ xhr.setRequestHeader("Accept", "application/json");
+ xhr.setRequestHeader("Content-Type", "application/json;charset=UTF-8");
+ xhr.setRequestHeader("Authorization", "Bearer " + __apifxn_get_token());
+ xhr.send(null);
+ break;
+ case "POST":
+ xhr.open('POST', sz_url);
+ xhr.setRequestHeader("Accept", "application/json");
+ xhr.setRequestHeader("Content-Type", "application/json;charset=UTF-8");
+ xhr.setRequestHeader("Authorization", "Bearer " + __apifxn_get_token());
+ xhr.send(JSON.stringify(dic_param)); // 폼 데이터 객체 전송
+ break;
+ case "PATCH":
+ xhr.open('PATCH', sz_url);
+ xhr.setRequestHeader("Accept", "application/json");
+ xhr.setRequestHeader("Content-Type", "application/json;charset=UTF-8");
+ xhr.setRequestHeader("Authorization", "Bearer " + __apifxn_get_token());
+ xhr.send(JSON.stringify(dic_param)); // 폼 데이터 객체 전송
+ break;
+ case "DELETE":
+ xhr.open('DELETE', sz_url, true);
+ xhr.setRequestHeader("Accept", "application/json");
+ xhr.setRequestHeader("Content-Type", "application/json;charset=UTF-8");
+ xhr.setRequestHeader("Authorization", "Bearer " + __apifxn_get_token());
+ xhr.send(null);
+ break;
+ }
+ });
+ }
+
+
+
+ //// 공개 API
+ return {
+ Init: function(ip, port, model, serial) {
+ return new Promise((resolve, reject) => {
+ if (HotelTV.state.token) {
+ let _token = HotelTV.state.token;
+ __apifxn_init({ 'dev_familly': model, 'serial_num': serial, 'svr_ip': ip, 'svr_port': port, 'api_ver': _token.version, "license": _token.license, "apikey": _token.apikey, "registered": _token.registered, "exist": _token.exist });
+ resolve(0);
+ } else {
+ // licenses api format
+ // /api/licenses/us761h0n/103INLV4B896
+ var sz_api_url = "http://" + ip + ":" + port + "/api/licenses" + "/" + model + "/" + serial;
+ console.log("Debug: request token url:" + sz_api_url);
+ __apifxn_CallCmsApi("GET", sz_api_url, "GetToken", null).then(_result => {
+ //console.log(`Success::>${_result.data}`);
+ HotelTV.state.token = JSON.parse(_result.data);
+ __apifxn_init({ 'dev_familly': model, 'serial_num': serial, 'svr_ip': ip, 'svr_port': port, 'api_ver': HotelTV.state.token.version, "license": HotelTV.state.token.license, "apikey": HotelTV.state.token.apikey, "registered": HotelTV.state.token.registered, "exist": HotelTV.state.token.exist });
+ resolve(0);
+ }).catch(_error => {
+ console.log(`Failure::>${_error.reason}`);
+ reject(_error.reason);
+ });
+ }
+ });
+ },
+
+ GetBaseUrl: function() {
+ return __apifxn_get_base_url();
+ },
+
+ CheckRegistration: function() {
+ return new Promise((resolve, reject) => {
+ let sz_api_url = __apifxn_get_registered();
+ resolve(sz_api_url);
+ });
+ },
+
+ DownloadData: function(dl_url) {
+ return new Promise((resolve, reject) => {
+ __apifxn_CallCmsApi("GET", dl_url, "DownloadData", null).then(_result => {
+ resolve(_result.data);
+ }).catch(_error => {
+ console.log(`Failure::>${_error.reason}`);
+ reject(_error.reason);
+ });
+ });
+ },
+
+ GetTranslation: function(group, locale) {
+ return new Promise((resolve, reject) => {
+ let sz_api_url = __apifxn_get_api_url("get_translation");
+ //let sz_api_param = null;
+ if (group) {
+ sz_api_url += `/&group=${group};`;
+ }
+ if (locale) {
+ sz_api_url += `/&locales=${locale};`;
+ }
+ __apifxn_CallCmsApi("GET", sz_api_url, "GetTranslation", null).then(_result => {
+ resolve(JSON.parse(_result.data));
+ }).catch(_error => {
+ console.log(`Failure::>${_error.reason}`);
+ reject(_error.reason);
+ });
+ });
+ },
+
+ GetServiceInfo: function() {
+ return new Promise((resolve, reject) => {
+ let sz_api_url = __apifxn_get_api_url("get_services");
+ __apifxn_CallCmsApi("GET", sz_api_url, "GetServiceInfo", null).then(_result => {
+ //console.log(`Success::>${_result.data}`);
+ resolve(JSON.parse(_result.data));
+ }).catch(_error => {
+ console.log(`Failure::>${_error.reason}`);
+ reject(_error.reason);
+ });
+ });
+ },
+
+ GetSettings: function() {
+ return new Promise((resolve, reject) => {
+ let sz_api_url = __apifxn_get_api_url("get_device_settings");
+ __apifxn_CallCmsApi("GET", sz_api_url, "GetDeviceSettings", null).then(_result => {
+ //console.log(`Success::>${_result.data}`);
+ resolve(JSON.parse(_result.data));
+ }).catch(_error => {
+ console.log(`Failure::>${_error.reason}`);
+ reject(_error.reason);
+ });
+ });
+ },
+
+ GetHotelInfo: function() {
+ return new Promise((resolve, reject) => {
+ let sz_api_url = __apifxn_get_api_url("get_site_info");
+ __apifxn_CallCmsApi("GET", sz_api_url, "GetHotelInfo", null).then(_result => {
+ ///console.log(`Success::>${_result.data}`);
+ resolve(JSON.parse(_result.data));
+ }).catch(_error => {
+ console.log(`Failure::>${_error.reason}`);
+ reject(_error.reason);
+ });
+ });
+ },
+
+ GetGuestInfo: function() {
+ return new Promise((resolve, reject) => {
+ let sz_api_url = __apifxn_get_api_url("get_guest_info");
+ __apifxn_CallCmsApi("GET", sz_api_url, "GetGuestInfo", null).then(_result => {
+ //console.log(`Success::>${_result.data}`);
+ resolve(JSON.parse(_result.data));
+ }).catch(_error => {
+ console.log(`Failure::>${_error.reason}`);
+ reject(_error.reason);
+ });
+ });
+ },
+
+ GetOpeningCtz: function() {
+ return new Promise((resolve, reject) => {
+ let sz_api_url = __apifxn_get_api_url("get_opening_ctz");
+ __apifxn_CallCmsApi("GET", sz_api_url, "GetOpeningCtz", null).then(_result => {
+ //console.log(`Success::>${_result.data}`);
+ resolve(JSON.parse(_result.data));
+ }).catch(_error => {
+ console.log(`Failure::>${_error.reason}`);
+ reject(_error.reason);
+ });
+ });
+ },
+
+ GetWeather: function() {
+ return new Promise((resolve, reject) => {
+ let sz_api_url = __apifxn_get_api_url("get_weather");
+ __apifxn_CallCmsApi("GET", sz_api_url, "GetWeather", null).then(_result => {
+ //console.log(`Success::>${_result.data}`);
+ resolve(JSON.parse(_result.data));
+ }).catch(_error => {
+ console.log(`Failure::>${_error.reason}`);
+ reject(_error.reason);
+ });
+ });
+ },
+
+ GetFlight: function() {
+ return new Promise((resolve, reject) => {
+ let sz_api_url = __apifxn_get_api_url("get_flight");
+ __apifxn_CallCmsApi("GET", sz_api_url, "GetFlight", null).then(_result => {
+ resolve(JSON.parse(_result.data));
+ }).catch(_error => {
+ console.log(`Failure::>${_error.reason}`);
+ reject(_error.reason);
+ });
+ });
+ },
+
+ GetProgramCtz: function() {
+ return new Promise((resolve, reject) => {
+ let sz_api_url = __apifxn_get_api_url("get_program_ctz");
+ __apifxn_CallCmsApi("GET", sz_api_url, "GetProgramCtz", null).then(_result => {
+ //console.log(`Success::>${_result.data}`);
+ resolve(JSON.parse(_result.data));
+ }).catch(_error => {
+ console.log(`Failure::>${_error.reason}`);
+ reject(_error.reason);
+ });
+ });
+ },
+
+ GetEpg: function() {
+ return new Promise((resolve, reject) => {
+ let sz_api_url = __apifxn_get_api_url("get_epg_info");
+ __apifxn_CallCmsApi("GET", sz_api_url, "GetEpg", null).then(_result => {
+ //console.log(`Success::>${_result.data}`);
+ resolve(JSON.parse(_result.data));
+ }).catch(_error => {
+ console.log(`Failure::>${_error.reason}`);
+ reject(_error.reason);
+ });
+ });
+ },
+
+ GetNews: function() {
+ return new Promise((resolve, reject) => {
+ let sz_api_url = __apifxn_get_api_url("get_news");
+ __apifxn_CallCmsApi("GET", sz_api_url, "GetNews", null).then(_result => {
+ //console.log(`Success::>${_result.data}`);
+ resolve(JSON.parse(_result.data));
+ }).catch(_error => {
+ console.log(`Failure::>${_error.reason}`);
+ reject(_error.reason);
+ });
+ });
+ },
+
+ GetMessage: function() {
+ return new Promise((resolve, reject) => {
+ let sz_api_url = __apifxn_get_api_url("get_message");
+ __apifxn_CallCmsApi("GET", sz_api_url, "GetMessage", null).then(_result => {
+ //console.log(`Success::>${_result.data}`);
+ resolve(JSON.parse(_result.data));
+ }).catch(_error => {
+ console.log(`Failure::>${_error.reason}`);
+ reject(_error.reason);
+ });
+ });
+ },
+
+ SetMessageStatus: function(msgID) {
+ return new Promise((resolve, reject) => {
+ let sz_api_url = __apifxn_get_api_url("get_message") + "/" + msgID;
+ __apifxn_CallCmsApi("GET", sz_api_url, "SetMessageStatus", null).then(_result => {
+ //console.log(`Success::>${_result.data}`);
+ let _rspJson = JSON.parse(_result.data);
+ if (_rspJson.status == 'ok') {
+ resolve(_rspJson.data);
+ } else {
+ resolve(null);
+ }
+ }).catch(_error => {
+ console.log(`Failure::>${_error.reason}`);
+ reject(_error.reason);
+ });
+ });
+ },
+
+ /**
+ * HotelTV API ::> get amenity carts info
+ * @param {dictionary} _item_id if _item_id isn't null it will return specified info with _item_id
+ */
+ GetAmenityCarts: function(_item_id) {
+ return new Promise((resolve, reject) => {
+ let sz_api_url = __apifxn_get_api_url("get_carts_amenity");
+ __apifxn_CallCmsApi((_item_id) ? "POST" : "GET", sz_api_url, "GetAmenityCarts", _item_id).then(_result => {
+ //console.log(`Success::>${_result.data}`);
+ resolve(JSON.parse(_result.data));
+ }).catch(_error => {
+ console.log(`Failure::>${_error.reason}`);
+ reject(_error.reason);
+ });
+ });
+ },
+
+ /**
+ * HotelTV API ::> put amenity carts info
+ * @param {dictionary} _item_id if _item_id isn't null it will return specified info with _item_id
+ */
+ PutAmenityCarts: function(_item_id, _quantity) {
+ return new Promise((resolve, reject) => {
+ let sz_api_url = __apifxn_get_api_url("put_carts_amenity");
+ __apifxn_CallCmsApi("POST", sz_api_url, "PutAmenityCarts", { "itemId": _item_id, "quantity": _quantity }).then(_result => {
+ //console.log(`Success::>${_result.data}`);
+ resolve(JSON.parse(_result.data));
+ }).catch(_error => {
+ console.log(`Failure::>${_error.reason}`);
+ reject(_error.reason);
+ });
+ });
+ },
+
+ /**
+ * HotelTV API ::> update amenity carts info
+ * @param {dictionary} _cart_id if _item_id isn't null it will return specified info with _item_id
+ */
+ UpdateAmenityCarts: function(_cart_id, _quantity) {
+ return new Promise((resolve, reject) => {
+ let sz_api_url = __apifxn_get_api_url("update_carts_amenity");
+ __apifxn_CallCmsApi("PATCH", `${sz_api_url}/${_cart_id}`, "UpdateAmenityCarts", { "quantity": _quantity }).then(_result => {
+ //console.log(`Success::>${_result.data}`);
+ resolve(JSON.parse(_result.data));
+ }).catch(_error => {
+ console.log(`Failure::>${_error.reason}`);
+ reject(_error.reason);
+ });
+ });
+ },
+
+ /**
+ * HotelTV API ::> delete amenity carts info
+ * @param {dictionary} _cart_id if _item_id isn't null it will return specified info with _item_id
+ */
+ DeleteAmenityCarts: function(_cart_id) {
+ return new Promise((resolve, reject) => {
+ let sz_api_url = __apifxn_get_api_url("delete_carts_amenity");
+ __apifxn_CallCmsApi("DELETE", `${sz_api_url}/${_cart_id}`, "DeleteAmenityCarts", null).then(_result => {
+ //console.log(`Success::>${_result.data}`);
+ resolve(JSON.parse(_result.data));
+ }).catch(_error => {
+ console.log(`Failure::>${_error.reason}`);
+ reject(_error.reason);
+ });
+ });
+ },
+
+ /**
+ * HotelTV API ::> get amenity order info
+ * @param {dictionary} _item_id if _item_id isn't null it will return specified info with _item_id
+ */
+ GetAmenityOrders: function(_item_id) {
+ return new Promise((resolve, reject) => {
+ let sz_api_url = __apifxn_get_api_url("get_order_amenity");
+ __apifxn_CallCmsApi((_item_id) ? "POST" : "GET", sz_api_url, "GetAmenityOrders", _item_id).then(_result => {
+ resolve(JSON.parse(_result.data));
+ }).catch(_error => {
+ console.log(`Failure::>${_error.reason}`);
+ reject(_error.reason);
+ });
+ });
+ },
+
+ /**
+ * HotelTV API ::> order amenity
+ * @param {dictionary} _cart_id if _item_id isn't null it will return specified info with _item_id
+ */
+ PutAmenityOrders: function(_cart_item) {
+ return new Promise((resolve, reject) => {
+ let sz_api_url = __apifxn_get_api_url("put_order_amenity");
+ __apifxn_CallCmsApi("POST", `${sz_api_url}`, "PutAmenityOrders", _cart_item).then(_result => {
+ //console.log(`Success::>${_result.data}`);
+ resolve(JSON.parse(_result.data));
+ }).catch(_error => {
+ console.log(`Failure::>${_error.reason}`);
+ reject(_error.reason);
+ });
+ });
+ },
+
+ /**
+ * HotelTV API ::> get room service carts info
+ * @param {dictionary} _item_id if _item_id isn't null it will return specified info with _item_id
+ */
+ GetRoomserviceCarts: function(_item_id) {
+ return new Promise((resolve, reject) => {
+ let sz_api_url = __apifxn_get_api_url("get_carts_roomservice");
+ __apifxn_CallCmsApi((_item_id) ? "POST" : "GET", sz_api_url, "GetRoomserviceCarts", _item_id).then(_result => {
+ //console.log(`Success::>${_result.data}`);
+ resolve(JSON.parse(_result.data));
+ }).catch(_error => {
+ console.log(`Failure::>${_error.reason}`);
+ reject(_error.reason);
+ });
+ });
+ },
+
+ /**
+ * HotelTV API ::> put room service carts info
+ * @param {dictionary} _item_id if _item_id isn't null it will return specified info with _item_id
+ */
+ PutRoomserviceCarts: function(_item_id, _quantity) {
+ return new Promise((resolve, reject) => {
+ let sz_api_url = __apifxn_get_api_url("put_carts_roomservice");
+ __apifxn_CallCmsApi("POST", sz_api_url, "PutRoomserviceCarts", { "itemId": _item_id, "quantity": _quantity }).then(_result => {
+ //console.log(`Success::>${_result.data}`);
+ resolve(JSON.parse(_result.data));
+ }).catch(_error => {
+ console.log(`Failure::>${_error.reason}`);
+ reject(_error.reason);
+ });
+ });
+ },
+
+ /**
+ * HotelTV API ::> update room service carts info
+ * @param {dictionary} _cart_id if _item_id isn't null it will return specified info with _item_id
+ */
+ UpdateRoomserviceCarts: function(_cart_id, _quantity) {
+ return new Promise((resolve, reject) => {
+ let sz_api_url = __apifxn_get_api_url("update_carts_roomservice");
+ __apifxn_CallCmsApi("PATCH", `${sz_api_url}/${_cart_id}`, "UpdateRoomserviceCarts", { "quantity": _quantity }).then(_result => {
+ //console.log(`Success::>${_result.data}`);
+ resolve(JSON.parse(_result.data));
+ }).catch(_error => {
+ console.log(`Failure::>${_error.reason}`);
+ reject(_error.reason);
+ });
+ });
+ },
+
+ /**
+ * HotelTV API ::> delete room service carts info
+ * @param {dictionary} _cart_id if _item_id isn't null it will return specified info with _item_id
+ */
+ DeleteRoomserviceCarts: function(_cart_id) {
+ return new Promise((resolve, reject) => {
+ let sz_api_url = __apifxn_get_api_url("delete_carts_roomservice");
+ __apifxn_CallCmsApi("DELETE", `${sz_api_url}/${_cart_id}`, "DeleteRoomserviceCarts", null).then(_result => {
+ //console.log(`Success::>${_result.data}`);
+ resolve(JSON.parse(_result.data));
+ }).catch(_error => {
+ console.log(`Failure::>${_error.reason}`);
+ reject(_error.reason);
+ });
+ });
+ },
+
+ /**
+ * HotelTV API ::> get room service order info
+ * @param {dictionary} _item_id if _item_id isn't null it will return specified info with _item_id
+ */
+ GetRoomserviceOrders: function(_item_id) {
+ return new Promise((resolve, reject) => {
+ let sz_api_url = __apifxn_get_api_url("get_order_roomservice");
+ __apifxn_CallCmsApi((_item_id) ? "POST" : "GET", sz_api_url, "GetRoomserviceOrders", _item_id).then(_result => {
+ resolve(JSON.parse(_result.data));
+ }).catch(_error => {
+ console.log(`Failure::>${_error.reason}`);
+ reject(_error.reason);
+ });
+ });
+ },
+
+ /**
+ * HotelTV API ::> order room service
+ * @param {dictionary} _cart_id if _item_id isn't null it will return specified info with _item_id
+ */
+ PutRoomserviceOrders: function(_cart_item) {
+ return new Promise((resolve, reject) => {
+ let sz_api_url = __apifxn_get_api_url("put_order_roomservice");
+ __apifxn_CallCmsApi("POST", `${sz_api_url}`, "PutRoomserviceOrders", _cart_item).then(_result => {
+ //console.log(`Success::>${_result.data}`);
+ resolve(JSON.parse(_result.data));
+ }).catch(_error => {
+ console.log(`Failure::>${_error.reason}`);
+ reject(_error.reason);
+ });
+ });
+ },
+
+ ReportBrief: function(_dev_inf, _gst_info, _usage_inf) {
+ let _json_report = {
+ "updated": "YYYY-MM-DD HH:MM:SS",
+ "brnote": "IN-SERVICE",
+ "guest_language": "",
+ "guest_name": "Jason Smith",
+ "guest_checkin": "1899-12-31",
+ "guest_checkout": "1899-12-31",
+ "guest_roomid": "7635",
+ "ker_ver": "0.00.00",
+ "cpu_usage": [],
+ "free_mem": null,
+ "disk_space_free": {
+ "flash": { "total": 0, "free": 0, "used": 0, "percent": "0" },
+ "storage": { "total": 0, "free": 0, "used": 0, "percent": "0" }
+ },
+ "cpu_freq": { "current": 0, "min": 0, "max": 0 },
+ "ip_addr": "xxx.xxx.xxx.xxx",
+ "mac_addr": "",
+ "mac_wifi": "",
+ "mac_bt": "",
+ "speed": 0,
+ "manufacture": "LG",
+ "model": "",
+ "hw_ver": "1.00",
+ "sw_ver": "1.1.5",
+ "scr_resolution": "1920x1080@60.00Hz - Full screen",
+ "temp": 0,
+ "uptime": {
+ "second": 344632,
+ "string": "03d23h43m52s"
+ },
+ "api_ver": "v1"
+ };
+
+ const _fxn_cvtDateFmt1 = function(_date) {
+ var _year = _date.getFullYear();
+ var _month = _date.getMonth() + 1;
+ if (_month < 10) _month = '0' + _month;
+ var _day = _date.getDate();
+ if (_day < 10) _day = '0' + _day;
+ var _hour = _date.getHours();
+ if (_hour < 10) _hour = '0' + _hour;
+ var _min = _date.getMinutes();
+ if (_min < 10) _min = '0' + _min;
+ var _sec = _date.getSeconds();
+ if (_sec < 10) _sec = '0' + _sec;
+ return _year + "-" + _month + "-" + _day + " " + _hour + ":" + _min + ":" + _sec;
+ };
+
+ const _fxn_sec2Date = function toDateTime(secs) {
+ var __t = new Date(1970, 0, 1); // Epoch
+ __t.setSeconds(secs);
+ var _day = (__t.getDate() - 1);
+ if (_day < 10) _day = '0' + _day;
+ var _hour = __t.getHours();
+ if (_hour < 10) _hour = '0' + _hour;
+ var _min = __t.getMinutes();
+ if (_min < 10) _min = '0' + _min;
+ var _sec = __t.getSeconds();
+ if (_sec < 10) _sec = '0' + _sec;
+ return _day + "d" + _hour + "h" + _min + "m" + _sec + "s";
+ }
+ _json_report.updated = _fxn_cvtDateFmt1(new Date());
+ _json_report.ker_ver = _dev_inf.boot_version.major + "." + _dev_inf.boot_version.minor + "." + _dev_inf.boot_version.revision;
+ _json_report.cpu_usage = [_usage_inf.cpu];
+ _json_report.brnote = 'IN-SERVICE';
+ _json_report.free_mem = {
+ "available": 0,
+ "inactive": 0,
+ "cached": 0,
+ "shared": 0,
+ "total": (_usage_inf.mem.total * 1048576),
+ "percent": _usage_inf.mem.percent.toString(),
+ "free": (_usage_inf.mem.free * 1048576),
+ };
+ _json_report.guest_language = _gst_info.language;
+ _json_report.guest_name = _gst_info.name;
+ _json_report.guest_checkin = _gst_info.cidt;
+ _json_report.guest_checkout = _gst_info.codt;
+ _json_report.guest_roomid = _gst_info.roomid;
+ _json_report.ip_addr = _dev_inf.network_info.ip_address;
+ _json_report.mac_addr = _dev_inf.network_info.details[0].mac;
+ _json_report.mac_wifi = _dev_inf.network_info.details[1].mac;
+ _json_report.mac_bt = '';
+
+ _json_report.model = _dev_inf.model_name;
+ _json_report.hw_ver = _dev_inf.hardware_version.major + "." + _dev_inf.hardware_version.minor;
+ _json_report.sw_ver = _dev_inf.hcap_middleware_version.major + "." + _dev_inf.hcap_middleware_version.minor + "." + _dev_inf.hcap_middleware_version.revision;
+ _json_report.scr_resolution = _dev_inf.display_resolution;
+
+ _json_report.uptime.second = Math.floor(_dev_inf.uptime / 1000);
+ _json_report.uptime.string = _fxn_sec2Date(_json_report.uptime.second);
+
+ let sz_api_url = __apifxn_get_api_url("set_device_status");
+ __apifxn_CallCmsApi("POST", sz_api_url, "SetDeviceStatus", _json_report).then(_result => {
+ console.log(`Success::>${_result.data}`);
+ }).catch(_error => {
+ console.log(`Failure::>${_error.reason}`);
+ });
+ },
+ }
+})();
\ No newline at end of file
diff --git a/procentric/application/lib/hoteltv.hcap.js b/procentric/application/lib/hoteltv.hcap.js
new file mode 100755
index 0000000..c094b74
--- /dev/null
+++ b/procentric/application/lib/hoteltv.hcap.js
@@ -0,0 +1,1591 @@
+/**
+ * Copyright (c) 2020
+ *
+ * CENTIRM HotelTV HCAP module javascript.
+ *
+ * @summary short description for the file
+ * @author Joel
+ *
+ * Created at : 2020-11-26 02:21:56
+ * Last modified : 2020-11-26 15:31:40
+ */
+HotelTV.namespace('HotelTV.hcap');
+HotelTV.hcap = (function() {
+ //// 의존 관계 선언
+
+
+ //// 비공개 프로퍼티
+ // var hcap_property_key = ['hcap_js_extension_version', 'hcap_middleware_version', 'model_name', 'platform_version',
+ // 'serial_number', 'number_of_tuner', 'support_language_list', 'osd_layer_id', 'room_number', 'single_decoding',
+ // 'browser_network_error_handling', 'soft_ap_ui', 'clock_display', 'asl_mode', 'rms_trusted_ip',
+ // 'input_splash_image', 'boot_sequence_option', 'tv_channel_attribute_floating_ui', 'browser_https_security_level',
+ // 'dmr',
+ // 'netinfo',
+ // 'pro_centric_server_info',
+ // ];
+ let hcap_property_key = ['hcap_js_extension_version', 'hcap_middleware_version', 'model_name', 'platform_version',
+ 'micom_version', 'boot_version', 'platform_src_revision', 'ptc_version', 'serial_number', 'display_resolution',
+ 'number_of_tuner', 'support_language_list', 'language', 'country', 'gmt_offset_in_minute', 'daylight_saving', 'boot_sequence_option',
+ 'application_channel_control', 'application_update_on_startup', 'application_update_in_shutdown',
+ 'osd_layer_id', 'key_delivery_to_simplink',
+ 'wol_w', 'wol_m',
+ 'single_decoding',
+ 'inband_data_service_mhp', 'inband_data_service_mheg', 'inband_data_service_hbbtv',
+ 'security_level', 'tv_name', 'wifi_screen_share',
+ 'smart_share', 'smart_pairing', 'dmr', 'browser_https_security_level',
+ 'clock_display', 'teletext', 'secure_mmr_pairing', 'dial', 'alljoyn', 'clock_source', 'xait_version',
+ 'asl_mode', 'screensaver_control', 'rms_trusted_ip', 'lg_service_xml_version', 'cec_device_control',
+ 'input_splash_image', 'block_usb', 'tv_channel_attribute_floating_ui',
+ 'instant_power', 'hardware_version',
+ 'network_info',
+ 'soft_ap_ui', "soft_ap", "soft_ap_password",
+ 'end_of_item'
+ ];
+ const g_media = {
+ 'hndl': null,
+ 'status': 'stop',
+ 'pipeline': false,
+ 'tm_lststat': null,
+ };
+
+ const g_hcap_info = {
+ 'preapp': null,
+ };
+
+
+ /// 초기화 루틴
+
+
+
+
+ //// 비공개 매써드
+ /**
+ * HCAP Wrapper Function::> Get ProCentric Server Info(Realted HCAP API:hcap.power.reboot)
+ * @param {string} sz_key property key name.
+ * @param {callback} callback is callback object
+ */
+ function __hcapfxn_Reboot() {
+ hcap.power.reboot({
+ "onSuccess": function() {
+ console.log("onSuccess");
+ },
+ "onFailure": function(f) {
+ console.log("onFailure : errorMessage = " + f.errorMessage);
+ }
+ });
+ };
+
+ /**
+ * HCAP Wrapper Function::> Get ProCentric Server Info(Realted HCAP API:hcap.system.setBrowserDebugMode)
+ * @param {string} sz_key property key name.
+ * @param {callback} callback is callback object
+ */
+ function __hcapfxn_setBrowserDebugMode(enable) {
+ hcap.system.setBrowserDebugMode({
+ "debugMode": enable == true ? true : false,
+ "onSuccess": function() {
+ console.log("onSuccess: browser debug mode enabled");
+ },
+ "onFailure": function(f) {
+ console.log("onFailure : errorMessage = " + f.errorMessage);
+ }
+ });
+ };
+
+ /**
+ * HCAP Wrapper Function::> Get Device Properties(Realted HCAP API:hcap.property.getProperty)
+ * @param {string} sz_key property key name.
+ * @param {callback} callback is callback object
+ */
+ function __hcapfxn_get_property(sz_key) {
+ return new Promise((resolve, reject) => {
+ let param = {
+ "key": sz_key,
+ "onSuccess": function(s) { resolve({ "key": sz_key, "value": s.value }) },
+ //"onFailure": function(f) { reject({ "key": sz_key, "value": "unknown" }) }
+ "onFailure": function(f) { resolve({ "key": sz_key, "value": "unknown" }) }
+ };
+ hcap.property.getProperty(param);
+ });
+ };
+
+ /**
+ * HCAP Wrapper Function::> Get Device Properties(Realted HCAP API:hcap.property.setProperty)
+ * @param {string} sz_key property key name.
+ * @param {callback} callback is callback object
+ */
+ function __hcapfxn_set_property(sz_key, value) {
+ return new Promise((resolve, reject) => {
+ let param = {
+ "key": sz_key,
+ "value": value.toString(),
+ "onSuccess": function(s) { resolve({ "key": sz_key, "value": value }) },
+ "onFailure": function(f) { resolve({ "key": sz_key, "value": "unknown" }) }
+ };
+ hcap.property.setProperty(param);
+ });
+ };
+
+ /**
+ * HCAP Wrapper Function::> Get Device Networn Information(Realted HCAP API:hcap.network.getNetworkInformation)
+ * @param {string} sz_key property key name.
+ * @param {callback} callback is callback object
+ */
+ function __hcapfxn_get_netinfo(sz_key, callback) {
+ return new Promise((resolve, reject) => {
+ let param = {
+ "onSuccess": function(p) {
+ let _info = p;
+ _info['details'] = {};
+ hcap.network.getNumberOfNetworkDevices({
+ "onSuccess": function(s) {
+ //console.log("onSuccess : the number of network devices = " + s.count);
+ for (var i = 0; i < s.count; i++) {
+ (function(k) {
+ hcap.network.getNetworkDevice({
+ "index": k,
+ "onSuccess": function(r) {
+ console.log("onSuccess : networkMode = " + r.networkMode +
+ "\n name = " + r.name +
+ "\n mac = " + r.mac +
+ "\n dhcp = " + r.dhcp +
+ "\n ip = " + r.ip +
+ "\n gateway = " + r.gateway +
+ "\n netmask = " + r.netmask +
+ "\n primary dns = " + r.primaryDns +
+ "\n secondary dns = " + r.secondaryDns);
+ delete r.command;
+ delete r.command_id;
+ _info['details'][k] = r;
+ if ((k + 1) == s.count) {
+ resolve({ "key": sz_key, "value": _info })
+ }
+ },
+ "onFailure": function(r) {
+ console.log("onFailure : errorMessage = " + r.errorMessage);
+ resolve({ "key": sz_key, "value": null });
+ }
+ });
+ })(i);
+ }
+ },
+ "onFailure": function(f) {
+ console.log("onFailure : errorMessage = " + f.errorMessage);
+ resolve({ "key": sz_key, "value": null })
+ }
+ });
+
+ //resolve({ "key": sz_key, "value": p })
+ },
+ "onFailure": function(f) { resolve({ "key": sz_key, "value": null }) }
+ };
+ hcap.network.getNetworkInformation(param);
+ });
+ };
+
+ /**
+ * HCAP Wrapper Function::> Get ProCentric Server Info(Realted HCAP API:hcap.system.getProcentricServer)
+ * @param {string} sz_key property key name.
+ * @param {callback} callback is callback object
+ */
+ function __hcapfxn_get_pctrsvrinfo(sz_key, callback) {
+ return new Promise((resolve, reject) => {
+ let param = {
+ "onSuccess": function(p) { resolve({ "key": sz_key, "info": p }) },
+ "onFailure": function(f) { resolve({ "key": sz_key, "info": null }); }
+ }
+ hcap.system.getProcentricServer(param);
+ });
+ };
+
+ /**
+ * HCAP Wrapper Function::> Get ProCentric Server Info(Realted HCAP API:hcap.system.getHotelMode)
+ * @param {string} sz_key property key name.
+ * @param {callback} callback is callback object
+ */
+ function __hcapfxn_get_pctrhotelmodeinfo(callback) {
+ let param = {
+ "onSuccess": function(p) { callback({ "info": p.hotelMode }); },
+ "onFailure": function(f) { callback({ "info": null, errmsg: f.errorMessage }); }
+ }
+ hcap.property.getHotelMode(param);
+ };
+
+ /**
+ * HCAP Wrapper Function::> Get Cpu TIme
+ * @param {callback} callback is callback object
+ */
+ function __hcapfxn_get_cpuTime(callback) {
+ let param = {
+ "onSuccess": function(param) {
+ //console.log("onSuccess : cpu time(milliseconds) = " + param.cpuTime);
+ if (callback != null) {
+ callback(param.cpuTime);
+ }
+ },
+ "onFailure": function(f) {
+ console.log("onFailure : errorMessage = " + f.errorMessage);
+ }
+ }
+ hcap.time.getCpuTime(param);
+ };
+
+ /**
+ * HCAP Wrapper Function::> Set Video Window size(Realted HCAP API:hcap.video.setVideoSize)
+ * @param {number} _sx start x position
+ * @param {number} _sy start x position
+ * @param {number} _width width
+ * @param {number} _height height
+ */
+ function __hcapfxn_set_vidwinsize(_sx, _sy, _width, _height) {
+ hcap.video.setVideoSize({
+ "x": _sx,
+ "y": _sy,
+ "width": _width,
+ "height": _height,
+ "onSuccess": function() {
+ console.log("onSuccess : setVideoSize");
+ },
+ "onFailure": function(f) {
+ console.log("onFailure : errorMessage = " + f.errorMessage);
+ }
+ });
+ };
+
+ /**
+ * HCAP Wrapper Function::> Get Device Resourcee status(CPU usage)
+ */
+ function __hcapfxn_get_cpuUsage() {
+ return new Promise((resolve, reject) => {
+ let param = {
+ "onSuccess": function(s) { resolve({ "key": "cpu_usage", "value": s.percentage }) },
+ "onFailure": function(f) { resolve({ "key": "cpu_usage", "value": -1 }) }
+ };
+ hcap.system.getCpuUsage(param);
+ });
+ };
+
+ /**
+ * HCAP Wrapper Function::> Get Device Resourcee status(MEM usage)
+ */
+ function __hcapfxn_get_memUsage() {
+ return new Promise((resolve, reject) => {
+ let param = {
+ "onSuccess": function(s) { resolve({ "key": "mem_usage", "value": { "total": s.totalmemory, "free": s.freememory, "percent": s.percentage } }) },
+ "onFailure": function(f) { resolve({ "key": "mem_usage", "value": -1 }) }
+ };
+ hcap.system.getMemoryUsage(param);
+ });
+ };
+
+ /**
+ * HCAP Wrapper Function::> Play channel
+ * @param {string} _type channel type
+ * @param {dictionary} _param channel parameter
+ */
+ function __hcapfxn_play_channel(_type, _param) {
+ // IP channel class 2 change request
+ if (_type === "ip") {
+ hcap.channel.requestChangeCurrentChannel({
+ "channelType": hcap.channel.ChannelType.IP,
+ "ip": _param.ip,
+ "port": _param.port,
+ "ipBroadcastType": _param.ptype == "rtp" ? hcap.channel.IpBroadcastType.RTP : hcap.channel.IpBroadcastType.UDP,
+ "onSuccess": function() {
+ console.log("onSuccess");
+ },
+ "onFailure": function(f) {
+ console.log("onFailure : errorMessage = " + f.errorMessage);
+ }
+ });
+ } else if (_type === "rf_analog_ntsc") {
+ hcap.channel.requestChangeCurrentChannel({
+ "channelType": hcap.channel.ChannelType.RF,
+ "majorNumber": _param.major,
+ "minorNumber": _param.minor,
+ "rfBroadcastType": hcap.channel.RfBroadcastType.ANALOG_NTSC,
+ "onSuccess": function() {
+ console.log("onSuccess");
+ },
+ "onFailure": function(f) {
+ console.log("onFailure : errorMessage = " + f.errorMessage);
+ }
+ });
+ }
+ }
+
+
+ /**
+ * HCAP Wrapper Function::> Play media
+ * @param {string} _type channel type
+ * @param {dictionary} _param channel parameter
+ */
+ function __hcapfxn_play_media(uri_media, uri_srt, mime_typ, repeat, cb_play_ok, cb_play_err) {
+ if (g_media.pipeline == true) {
+ g_media.hndl.stop({
+ "onSuccess": function() {
+ g_media.hndl.destroy({
+ "onSuccess": function() {
+ g_media.hndl = hcap.Media.createMedia({
+ "url": uri_media,
+ "mimeType": mime_typ
+ });
+
+ console.log("Media.createMedia = " + g_media.hndl);
+ g_media.hndl.play({
+ "repeatCount": repeat,
+ "onSuccess": function() {
+ console.log("onSuccess : playVOD -> " + uri_media);
+ g_media.status = 'play';
+ if (cb_play_ok != null) {
+ cb_play_ok();
+ }
+ },
+ "onFailure": function(f) {
+ console.log("onFailure : errorMessage = " + f.errorMessage);
+ if (cb_play_err != null) {
+ cb_play_err();
+ }
+ }
+ });
+ },
+ "onFailure": function(f) {
+ console.log("onFailure : errorMessage = " + f.errorMessage);
+ if (cb_play_err != null) {
+ cb_play_err();
+ }
+ }
+ });
+ },
+ "onFailure": function(f) {
+ console.log("onFailure : errorMessage = " + f.errorMessage);
+ if (f.errorMessage == 'already destroyed.') {
+ g_media.hndl = hcap.Media.createMedia({
+ "url": uri_media,
+ "mimeType": mime_typ
+ });
+
+ console.log("Media.createMedia = " + g_media.hndl);
+ g_media.hndl.play({
+ "repeatCount": repeat,
+ "onSuccess": function() {
+ console.log("onSuccess : playVOD -> " + uri_media);
+ g_media.status = 'play';
+ if (cb_play_ok != null) {
+ cb_play_ok();
+ }
+ },
+ "onFailure": function(f) {
+ console.log("onFailure : errorMessage = " + f.errorMessage);
+ if (cb_play_err != null) {
+ cb_play_err();
+ }
+ }
+ });
+ } else {
+ if (cb_play_err != null) {
+ cb_play_err();
+ }
+ }
+ }
+ });
+ } else {
+ g_media.pipeline = true;
+ hcap.Media.startUp({
+ "onSuccess": function() {
+ g_media.hndl = hcap.Media.createMedia({
+ "url": uri_media,
+ "mimeType": mime_typ
+ });
+
+ console.log("Media.createMedia = " + g_media.hndl);
+ g_media.hndl.play({
+ "repeatCount": repeat,
+ "onSuccess": function() {
+ console.log("onSuccess : playVOD -> " + uri_media);
+ g_media.status = 'play';
+ if (cb_play_ok != null) {
+ cb_play_ok();
+ }
+ },
+ "onFailure": function(f) {
+ console.log("onFailure : errorMessage = " + f.errorMessage);
+ if (cb_play_err != null) {
+ cb_play_err();
+ }
+ }
+ });
+ },
+ "onFailure": function(f) {
+ console.log("onFailure : errorMessage = " + f.errorMessage);
+ if (cb_play_err != null) {
+ cb_play_err();
+ }
+ }
+ });
+ }
+ }
+
+ /**
+ * HCAP Wrapper Function::> Media Shutdown
+ */
+ function __hcapfxn_media_shutdown() {
+ return new Promise((resolve, reject) => {
+ if (g_media.hndl != null) {
+ g_media.hndl.stop({
+ "onSuccess": function() {
+ g_media.hndl.destroy({
+ "onSuccess": function() {
+ hcap.Media.shutDown({
+ "onSuccess": function() {
+ console.log("shutDown onSuccess");
+ g_media.status = 'stop';
+ resolve();
+ },
+ "onFailure": function(f) {
+ console.log("onFailure : errorMessage = " + f.errorMessage);
+ reject(f.errorMessage);
+ }
+ });
+ },
+ "onFailure": function(f) {
+ console.log("onFailure : errorMessage = " + f.errorMessage);
+ reject(f.errorMessage);
+ }
+ });
+ },
+ "onFailure": function(f) {
+ console.log("onFailure : errorMessage = " + f.errorMessage);
+ reject(f.errorMessage);
+ }
+ });
+ } else {
+ console.log("g_media.hndl is null");
+ resolve("g_media.hndl is null");
+ }
+ });
+ }
+
+
+ //// 공개 API
+ return {
+ Init: function() {
+ hcap.channel.stopCurrentChannel({
+ "onSuccess": null,
+ "onFailure": function(f) {
+ console.log("onFailure : errorMessage = " + f.errorMessage);
+ }
+ });
+ },
+
+ SetBrowserDebug: function(__en_dbg_hcap, __en_dbg_brw) {
+ /** Disable HCAP debug message turn off */
+ if (__en_dbg_hcap == false) {
+ extDisableHcapConsoleLog = true;
+ }
+ __hcapfxn_setBrowserDebugMode(__en_dbg_brw);
+ },
+
+
+ PwrOff: function() {
+ hcap.power.powerOff({
+ "onSuccess": function() {
+ console.log("onSuccess:: > Power OFF");
+ },
+ "onFailure": function(f) {
+ console.log("onFailure : errorMessage = " + f.errorMessage);
+ }
+ });
+ },
+
+ Reboot: function() {
+ __hcapfxn_Reboot();
+ },
+
+
+ GetDevInfo: function() {
+ return new Promise((resolve, reject) => {
+ const _pmFxnArProperty = [];
+ // __hcapfxn_get_property("display_resolution").then(result => {
+ // console.log("R::>" + result.key + ":" + result.value);
+ // }).catch(err => {
+ // console.log("E::>" + err.key);
+ // });
+
+ // Device Information
+ for (let i = 0; i < hcap_property_key.length; i++) {
+ if (hcap_property_key[i] != 'end_of_item') {
+ if (hcap_property_key[i] == 'network_info') {
+ _pmFxnArProperty.push(__hcapfxn_get_netinfo(hcap_property_key[i]));
+ } else {
+ _pmFxnArProperty.push(__hcapfxn_get_property(hcap_property_key[i]));
+ }
+ }
+ }
+ Promise.all(_pmFxnArProperty)
+ .then(_ret => {
+ let _devinfo = HotelTV.devinfo;
+ for (let i = 0; i < _ret.length; i++) {
+ let _dic_item = _ret[i];
+ if (_dic_item.value != null) {
+ if (_dic_item.value != "unknown" && (
+ _dic_item.key == 'hcap_js_extension_version' ||
+ _dic_item.key == 'hcap_middleware_version' ||
+ _dic_item.key == 'platform_version' ||
+ _dic_item.key == 'boot_version' ||
+ _dic_item.key == 'ptc_version' ||
+ _dic_item.key == 'hardware_version'
+ )) {
+ let _verinfo = _dic_item.value.split(".");
+ if (_verinfo.length == 1) {
+ _devinfo[_dic_item.key] = { "major": _verinfo[0], "minor": "00" };
+ } else if (_verinfo.length == 3) {
+ _devinfo[_dic_item.key] = { "major": _verinfo[0], "minor": _verinfo[1], "revision": _verinfo[2] };
+ } else if (_verinfo.length == 4) {
+ _devinfo[_dic_item.key] = { "major": _verinfo[0], "minor": _verinfo[1], "revision": _verinfo[2] + _verinfo[3] };
+ }
+ } else {
+ _devinfo[_dic_item.key] = _dic_item.value;
+
+ if (_dic_item.key == 'network_info') {
+ delete _devinfo[_dic_item.key].command;
+ delete _devinfo[_dic_item.key].command_id;
+ }
+ }
+ } else {
+ console.log(`ERROR::>Item[${_dic_item.key}] is NULL::>`);
+ }
+ //console.log(`Item[${_dic_item.key}] ::> ${_dic_item.value}`);
+ };
+
+ //Server Information
+ __hcapfxn_get_pctrsvrinfo("pro_centric_server_info").then(result => {
+ let _svrinfo = HotelTV.svrinfo;
+ let _info = result.info;
+ if (_info.media === "rf") {
+ console.log(`PTC server type[${_info.rfServer.type}], data channel number = ${_info.rfServer.dataChannelNumber}`);
+ console.log(`PTC server type[${_info.rfServer.type}], frequency = ${_info.rfServer.freqeuncy}`);
+ } else if (_info.media === "ip") {
+ if (_info.ipServer.type === "ip") {
+ console.log(`PTC server type[${_info.ipServer.type}], ip = ${_info.ipServer.ip} port=${_info.ipServer.port}`);
+ _svrinfo['ipaddr'] = _info.ipServer.ip;
+ _svrinfo['port'] = _info.ipServer.port;
+ } else if (p.ipServer.type === "domain_name") {
+ console.log(`PTC server type[${_info.ipServer.type}], dns = ${_info.ipServer.domainName} port=${_info.ipServer.port}`);
+ }
+ }
+ _svrinfo['media'] = _info.media;
+ _svrinfo['typ_ipsvr'] = _info.ipServer.type;
+ resolve(0);
+ });
+ });
+ });
+ },
+
+ ShowDevInfo: function() {
+ return new Promise((resolve, reject) => {
+ let _devinfo = HotelTV.devinfo;
+ for (let key in _devinfo) {
+ console.log("Device Info::Key[" + key + "]: " + _devinfo[key]);
+ }
+ resolve(0);
+ });
+ },
+
+ SetDevice: function(config) {
+ return new Promise((resolve, reject) => {
+ const _pmFxnArProperty = [];
+ let _devinfo = HotelTV.devinfo;
+ let _devconfig = config;
+ let need_to_reboot = false;
+
+ // STEP#001::> HOTEL MODE
+ hcap.mode.getHcapMode({
+ "onSuccess": function(s) {
+ console.log("onSuccess : current hcap mode = " + s.mode);
+ if (s.mode != hcap.mode.HCAP_MODE_1) {
+ hcap.mode.setHcapMode({
+ "mode": hcap.mode.HCAP_MODE_1,
+ "onSuccess": function() {
+ console.log("onSuccess");
+ },
+ "onFailure": function(f) {
+ console.log("onFailure : errorMessage = " + f.errorMessage);
+ }
+ });
+ }
+ },
+ "onFailure": function(f) {
+ console.log("onFailure : errorMessage = " + f.errorMessage);
+ }
+ });
+
+ // STEP#002::> Start Channel
+ hcap.channel.getStartChannel({
+ "onSuccess": function(s) {
+ console.log("onSuccess :" +
+ "\n channel type : " + s.channelType +
+ "\n logical number : " + s.logicalNumber +
+ "\n frequency : " + s.frequency +
+ "\n program number : " + s.programNumber +
+ "\n major number : " + s.majorNumber +
+ "\n minor number : " + s.minorNumber +
+ "\n satellite ID : " + s.satelliteId +
+ "\n polarization : " + s.polarization +
+ "\n rf broadcast type : " + s.rfBroadcastType +
+ "\n ip : " + s.ip +
+ "\n port : " + s.port +
+ "\n ip broadcast type : " + s.ipBroadcastType +
+ "\n symbol rate : " + s.symbolRate +
+ "\n pcr pid : " + s.pcrPid +
+ "\n video pid : " + s.videoPid +
+ "\n video stream type : " + s.videoStreamType +
+ "\n audio pid : " + s.audioPid +
+ "\n audio stream type : " + s.audioStreamType +
+ "\n signal strength : " + s.signalStrength +
+ "\n source address : " + s.sourceAddress);
+ if (s.channelType != hcap.channel.ChannelType.UNKNOWN) {
+ // set start channel with RF channel class 2
+ hcap.channel.setStartChannel({
+ "channelType": hcap.channel.ChannelType.UNKNOWN,
+ "onSuccess": function() {
+ console.log("onSuccess::StartChanell Cetting");
+ },
+ "onFailure": function(f) {
+ console.log("onFailure : errorMessage = " + f.errorMessage);
+ }
+ });
+ }
+ },
+ "onFailure": function(f) {
+ console.log("onFailure : errorMessage = " + f.errorMessage);
+ }
+ });
+
+ // STEP#003::> CENTIRM's Remote Controller Registr
+ let _rmcTbl_CT_default = [
+ { "_keyCode": 0x847912ed, "_virCode": hcap.key.Code.POWER }, //PWR KEY
+ { "_keyCode": 0x847907f8, "_virCode": hcap.key.Code.LEFT }, //LEFT KEY
+ { "_keyCode": 0x847909f6, "_virCode": hcap.key.Code.RIGHT }, //RIGHT KEY
+ { "_keyCode": 0x847908f7, "_virCode": hcap.key.Code.ENTER }, //OK KEY
+ { "_keyCode": 0x847905fa, "_virCode": hcap.key.Code.UP }, //UP KEY
+ { "_keyCode": 0x847900ff, "_virCode": hcap.key.Code.DOWN }, //DOWN KEY
+ { "_keyCode": 0x84791ae5, "_virCode": hcap.key.Code.BACK }, //BACK KEY
+ { "_keyCode": 0x84791fe0, "_virCode": hcap.key.Code.STOP }, //STOP KEY
+ { "_keyCode": 0x847910ef, "_virCode": hcap.key.Code.VOL_UP }, //VOL UP KEY
+ { "_keyCode": 0x84790ff0, "_virCode": hcap.key.Code.VOL_DOWN }, //VOL DOWN KEY
+ { "_keyCode": 0x84790af5, "_virCode": hcap.key.Code.PORTAL }, //PORTAL KEY
+ ];
+
+ _rmcTbl_CT_default.forEach(function(_item) {
+ //console.log(`${_item._keyCode} map as ${_item._virCode}`);
+ hcap.key.addKeyItem({
+ "keycode": _item._keyCode,
+ "virtualKeycode": _item._virCode,
+ "attribute": 0,
+ "onSuccess": null,
+ "onFailure": function(f) {
+ console.log("onFailure : errorMessage = " + f.errorMessage);
+ }
+ });
+ })
+
+ // STEP#004::> Power Mode
+ if (_devinfo["instant_power"] !== undefined) {
+ if (_devinfo["instant_power"] != 0) {
+ console.log("INSTANT POWER MODE::> off");
+ __hcapfxn_set_property('instant_power', 0).then(_result => {
+ hcap.power.getPowerMode({
+ "onSuccess": function(s) {
+ console.log("onSuccess power mode " + s.mode);
+ if (s.mode != hcap.power.PowerMode.WARM) {
+ hcap.power.setPowerMode({
+ "mode": hcap.power.PowerMode.WARM,
+ "onSuccess": null,
+ "onFailure": function(f) {
+ console.log("onFailure : errorMessage = " + f.errorMessage);
+ }
+ });
+ }
+ },
+ "onFailure": function(f) {
+ console.log("onFailure : errorMessage = " + f.errorMessage);
+ }
+ });
+ });
+ }
+ }
+
+ // STEP#00X::> SERVICE RELATED PARAMETERS
+ for (let _cfg in _devconfig) {
+ if (_cfg == 'video') {
+ for (let _item in _devconfig.video) {
+ if (_item == "resolution") {
+ if (_devconfig.video.resolution != _devinfo.display_resolution) {
+ console.log(`Try to set screen resolution ${_devinfo.display_resolution} to ${_devconfig.video.resolution}`);
+ _pmFxnArProperty.push(__hcapfxn_set_property('display_resolution', _devconfig.video.resolution));
+ }
+ }
+ }
+ } else if (_cfg == 'networks') {
+ let _netCfg = _devconfig[_cfg];
+ /* Note:
+ 동작 스킴
+ 1. WLAN이 HOST모드이면 이 디바이스는 WIFI로 접속
+ 2. 그외의 경우 ETH0를 통한 네트워크 접속 수행 */
+ /* Wireless Network Configuration */
+ if ('wlan0' in _netCfg) {
+ let _wlan_cfg = _netCfg['wlan0'];
+ if (_wlan_cfg.enable == true) {
+ // // Change TV Device Name(It will be used for SSID)
+ // if (_wlan_cfg.ssid && _devinfo['tv_name'] != _wlan_cfg.ssid) {
+ // _pmFxnArProperty.push(__hcapfxn_set_property('tv_name', _wlan_cfg.ssid));
+ // } else {
+ // _pmFxnArProperty.push(__hcapfxn_set_property('tv_name', "TV-" + HotelTV.guestinfo.room));
+ // }
+
+ console.log(`Net Cfg enabled: ${_wlan_cfg.name}`);
+ if (_wlan_cfg.apMode == 'nat') {
+ hcap.network.setSoftAP({
+ "channel": Number(_wlan_cfg.channel),
+ "signalStrength": Number(_wlan_cfg.signalStrength),
+ "vlanId": 0,
+ "vlanIp": _wlan_cfg.ipaddr,
+ "vlanSubnet": _wlan_cfg.subnet,
+ "vlanGateway": _wlan_cfg.gateway,
+ "mode": "nat",
+ "securityType": (_wlan_cfg.securityType == "open") ? "open" : "psk",
+ "onSuccess": function(s) {
+ console.log("onSuccess");
+ },
+ "onFailure": function(f) {
+ console.log("onFailure : errorMessage = " + f.errorMessage);
+ }
+ });
+ } else if (_wlan_cfg.apMode == 'bridge') {
+ // mode : bridge, securityType : psk
+ hcap.network.setSoftAP({
+ "channel": Number(_wlan_cfg.channel),
+ "signalStrength": Number(_wlan_cfg.signalStrength),
+ "mode": "bridge",
+ "securityType": (_wlan_cfg.securityType == "open") ? "open" : "psk",
+ "onSuccess": function(s) {
+ console.log("onSuccess");
+ },
+ "onFailure": function(f) {
+ console.log("onFailure : errorMessage = " + f.errorMessage);
+ }
+ });
+ } else if (_wlan_cfg.apMode == 'host') {
+ console.log(`Net Cfg failed: ${_wlan_cfg.name} Unsupported mode at the moment!!!`);
+ }
+ } else {
+ console.log(`Net Cfg disabled: ${_wlan_cfg.name}`);
+ }
+ }
+
+ /* Wire Network Configuration */
+ if ('eth0' in _netCfg) {
+ let _lan_cfg = _netCfg['eth0'];
+ if (_lan_cfg.enable == true) {
+ console.log(`Net Cfg enabled: ${_lan_cfg.name}`);
+ if (_lan_cfg.ipv4.enable == true) {
+ for (let _ndevIdx in _devinfo.network_info.details) {
+ _dev_iface_info = _devinfo.network_info.details[_ndevIdx];
+ if (_lan_cfg.name == _dev_iface_info.name) {
+ if (_lan_cfg.ipv4.method == 'dhcp' && _dev_iface_info.dhcp == false) {
+ need_to_reboot = true;
+ hcap.network.setNetworkDevice({
+ "index": Number(_ndevIdx),
+ "dhcp": true,
+ "onSuccess": function() {
+ console.log("onSuccess");
+ },
+ "onFailure": function(f) {
+ console.log("onFailure : errorMessage = " + f.errorMessage);
+ }
+ });
+ } else if (_lan_cfg.ipv4.method != 'dhcp' &&
+ ((_dev_iface_info.ip != _lan_cfg.ipv4.ipaddr) ||
+ (_dev_iface_info.gateway != _lan_cfg.ipv4.gateway) ||
+ (_dev_iface_info.netmask != _lan_cfg.ipv4.subnet) ||
+ (_dev_iface_info.primaryDns != _lan_cfg.ipv4.dns[0]) ||
+ (_dev_iface_info.dhcp == true))) {
+ need_to_reboot = true;
+ hcap.network.setNetworkDevice({
+ "index": Number(_ndevIdx),
+ "dhcp": false,
+ "ip": _lan_cfg.ipv4.ipaddr,
+ "gateway": _lan_cfg.ipv4.gateway,
+ "netmask": _lan_cfg.ipv4.subnet,
+ "primaryDns": _lan_cfg.ipv4.dns[0],
+ "secondaryDns": _lan_cfg.ipv4.dns[1],
+ "onSuccess": function() {
+ console.log("onSuccess");
+ },
+ "onFailure": function(f) {
+ console.log("onFailure : errorMessage = " + f.errorMessage);
+ }
+ });
+ }
+ }
+ }
+ } else {
+ console.log(`Net interface config: ${_lan_cfg.name} will be disabled...`);
+ }
+ } else {
+ console.log(`Net Cfg disabled: ${_lan_cfg.name}`);
+ }
+ }
+ } else if (_cfg == 'system') {
+
+ } else if (_cfg == 'audio') {
+ // TV Default Volume
+ hcap.volume.setVolumeLevel({
+ "level": Number(_devconfig[_cfg].defaultVolume.display),
+ "onSuccess": function() {
+ console.log("onSuccess Set to TV default volume set as " + _devconfig[_cfg].defaultVolume.display);
+ },
+ "onFailure": function(f) {
+ console.log("onFailure : errorMessage = " + f.errorMessage);
+ }
+ });
+ }
+ }
+
+ //Specifial parameters
+ if (_devinfo["boot_sequence_option"] !== undefined) {
+ if (_devinfo["boot_sequence_option"] != 1) {
+ _pmFxnArProperty.push(__hcapfxn_set_property('boot_sequence_option', 1));
+ }
+ }
+
+ // Clock Display
+ if (_devinfo["clock_display"] !== undefined) {
+ if (_devinfo["clock_display"] != 0) {
+ _pmFxnArProperty.push(__hcapfxn_set_property('clock_display', 0));
+ }
+ }
+
+ // Input splash Image
+ if (_devinfo["input_splash_image"] !== undefined) {
+ if (_devinfo["input_splash_image"] != 0) {
+ _pmFxnArProperty.push(__hcapfxn_set_property('input_splash_image', 0));
+ }
+ }
+
+ // USB Device Blocking
+ if (_devinfo["block_usb"] !== undefined) {
+ if (_devinfo["block_usb"] != 1) {
+ _pmFxnArProperty.push(__hcapfxn_set_property('block_usb', 1));
+ }
+ }
+
+ // WOL
+ if (_devinfo["wol_m"] !== undefined) {
+ if (_devinfo["wol_m"] != "normal") {
+ _pmFxnArProperty.push(__hcapfxn_set_property('wol_m', "normal"));
+ }
+ }
+
+ // WIFI SCREEN SHARE
+ if (_devinfo["wifi_screen_share"] !== undefined) {
+ if (_devinfo["wifi_screen_share"] != 0) {
+ _pmFxnArProperty.push(__hcapfxn_set_property('wifi_screen_share', 0));
+ }
+ }
+
+ // SMART SHARE
+ if (_devinfo["smart_share"] !== undefined) {
+ if (_devinfo["smart_share"] != 0) {
+ _pmFxnArProperty.push(__hcapfxn_set_property('smart_share', 0));
+ }
+ }
+
+ // SMART PARING
+ if (_devinfo["smart_pairing"] !== undefined) {
+ if (_devinfo["smart_pairing"] != 1) {
+ _pmFxnArProperty.push(__hcapfxn_set_property('smart_pairing', 1));
+ }
+ }
+
+ // DIAL
+ if (_devinfo["dial"] !== undefined) {
+ if (_devinfo["dial"] != 1) {
+ _pmFxnArProperty.push(__hcapfxn_set_property('dial', 1));
+ }
+ }
+
+ // DMR
+ if (_devinfo["dmr"] !== undefined) {
+ if (_devinfo["dmr"] != 0) {
+ _pmFxnArProperty.push(__hcapfxn_set_property('dmr', 0));
+ }
+ }
+
+ // SOFTAP UI
+ if (_devinfo["soft_ap_ui"] !== undefined) {
+ if (_devinfo["soft_ap_ui"] != 0) {
+ _pmFxnArProperty.push(__hcapfxn_set_property('soft_ap_ui', 0));
+ }
+ }
+
+ // SOFTAP
+ if (_devinfo["soft_ap"] !== undefined) {
+ if (_devinfo["soft_ap"] != 0) {
+ _pmFxnArProperty.push(__hcapfxn_set_property('soft_ap', 0));
+ }
+ }
+
+ // // OSD LAYER ID
+ // if (_devinfo["osd_layer_id"] !== undefined) {
+ // if (_devinfo["osd_layer_id"] != 0) {
+ // _pmFxnArProperty.push(__hcapfxn_set_property('osd_layer_id', 0));
+ // }
+ // }
+
+ // MISC
+ if (_devinfo["tv_channel_attribute_floating_ui"] !== undefined) {
+ if (_devinfo["tv_channel_attribute_floating_ui"] != 0) {
+ _pmFxnArProperty.push(__hcapfxn_set_property('tv_channel_attribute_floating_ui', 0));
+ }
+ }
+
+
+ //_pmFxnArProperty.push(__hcapfxn_set_property('clock_source', 'ntp'));
+
+ if (_pmFxnArProperty.length > 0) {
+ Promise.all(_pmFxnArProperty)
+ .then(_ret => {
+ for (let i = 0; i < _ret.length; i++) {
+ let _set_item = _ret[i];
+ let no_need_reboot_param = ["wifi_screen_share", "soft_ap", "soft_ap_ui", "osd_layer_id"];
+ if (no_need_reboot_param.indexOf(_set_item.key) !== -1) {
+ //Needed reboot the system
+ need_to_reboot = true;
+ }
+ console.log(`Device config[${_set_item.key}] set to ${_set_item.value}`);
+ }
+ });
+ resolve(need_to_reboot);
+ } else {
+ resolve(need_to_reboot);
+ }
+ }).catch(function(_err) {
+ console.log(`fail to perform SetDevice() ${_err}`);
+ });
+ },
+
+ VideoWinSize: function(size) {
+ let _res = HotelTV.devinfo.display_resolution.split("x");
+ let max_width = Number(_res[0]);
+ let max_height = Number(_res[1]);
+ let _pos_size = { 'sx': 0, 'sy': 0, 'width': max_width, 'height': max_height };
+ if (size != null) {
+ _pos_size['sx'] = size.sx;
+ _pos_size['sy'] = size.sy;
+ _pos_size['width'] = size.width
+ _pos_size['height'] = size.height;
+ }
+ __hcapfxn_set_vidwinsize(_pos_size['sx'], _pos_size['sy'], _pos_size['width'], _pos_size['height']);
+ },
+
+
+ MediaShutdown: function(cb_ok, cb_error) {
+ __hcapfxn_media_shutdown().then(function() {
+ if (cb_ok != null) {
+ cb_ok();
+ }
+ }).catch(function(err) {
+ console.log(err); // Error: Request is failed
+ if (cb_error != null) {
+ cb_error();
+ }
+ });
+ },
+
+ MediaPlay: function(uri_media, uri_srt, mime_typ, repeat, cb_play_ok, cb_play_err) {
+ if (g_media.tm_lststat == null) {
+ g_media.tm_lststat = new Date();
+ } else {
+ let _tm_cur = new Date();
+ let _tm_diff_ms = _tm_cur.getTime() - g_media.tm_lststat.getTime();
+ if (_tm_diff_ms < 2000) {
+ return;
+ }
+ g_media.tm_lststat = _tm_cur;
+ }
+
+ hcap.channel.getCurrentChannel({
+ "onSuccess": function(s) {
+ if (s.channelStatus == hcap.channel.ChannelStatus.AV_DISPLAYED ||
+ s.channelStatus == hcap.channel.ChannelStatus.AUDIO_ONLY_BLOCKED ||
+ s.channelStatus == hcap.channel.ChannelStatus.VIDEO_ONLY_BLOCKED) {
+ hcap.channel.stopCurrentChannel({
+ "onSuccess": function() {
+ __hcapfxn_play_media(uri_media, uri_srt, mime_typ, repeat, cb_play_ok, cb_play_err);
+ },
+ "onFailure": function(f) {
+ console.log("onFailure : errorMessage = " + f.errorMessage);
+ }
+ });
+ } else {
+ __hcapfxn_play_media(uri_media, uri_srt, mime_typ, repeat, cb_play_ok, cb_play_err);
+ }
+ },
+ "onFailure": function(f) {
+ __hcapfxn_play_media(uri_media, uri_srt, mime_typ, repeat, cb_play_ok, cb_play_err);
+ }
+ });
+ },
+
+ MediaStop: function(cb_stop_ok, cb_stop_err) {
+ if (g_media.hndl != null) {
+ g_media.hndl.stop({
+ "onSuccess": function() {
+ g_media.hndl.destroy({
+ "onSuccess": function() {
+ console.log("onSuccess");
+ if (cb_stop_ok != null) {
+ cb_stop_ok();
+ }
+ },
+ "onFailure": function(f) {
+ console.log("onFailure : errorMessage = " + f.errorMessage);
+ if (cb_stop_err != null) {
+ cb_stop_err();
+ }
+ }
+ });
+ },
+ "onFailure": function(f) {
+ console.log("onFailure : errorMessage = " + f.errorMessage);
+ if (cb_stop_err != null) {
+ cb_stop_err();
+ }
+ }
+ });
+ }
+ },
+
+ ChannelShutDown: function() {
+ // IP channel class 2 change request
+ // CHANNEL STATUS TABLE
+ // hcap.channel.ChannelStatus.UNKNOWN:0
+ // hcap.channel.ChannelStatus.AUDIO_VIDEO_NOT_BLOCKED:16
+ // hcap.channel.ChannelStatus.AV_DISPLAYED:16,
+ // hcap.channel.ChannelStatus.AUDIO_VIDEO_BLOCKED:33
+ // hcap.channel.ChannelStatus.NO_SIGNAL:33
+ // hcap.channel.ChannelStatus.AUDIO_ONLY_BLOCKED:34
+ // hcap.channel.ChannelStatus.VIDEO_ONLY_BLOCKED:35
+ hcap.channel.getCurrentChannel({
+ "onSuccess": function(s) {
+ console.log("onSuccess :" +
+ "\n channel status : " + s.channelStatus +
+ "\n channel type : " + s.channelType +
+ "\n logical number : " + s.logicalNumber +
+ "\n frequency : " + s.frequency +
+ "\n program number : " + s.programNumber +
+ "\n major number : " + s.majorNumber +
+ "\n minor number : " + s.minorNumber +
+ "\n satellite ID : " + s.satelliteId +
+ "\n polarization : " + s.polarization +
+ "\n rf broadcast type : " + s.rfBroadcastType +
+ "\n ip : " + s.ip +
+ "\n port : " + s.port +
+ "\n ip broadcast type : " + s.ipBroadcastType +
+ "\n symbol rate : " + s.symbolRate +
+ "\n pcr pid : " + s.pcrPid +
+ "\n video pid : " + s.videoPid +
+ "\n video stream type : " + s.videoStreamType +
+ "\n audio pid : " + s.audioPid +
+ "\n audio stream type : " + s.audioStreamType +
+ "\n signal strength : " + s.signalStrength +
+ "\n source address : " + s.sourceAddress);
+ if (s.channelStatus == hcap.channel.ChannelStatus.AV_DISPLAYED ||
+ s.channelStatus == hcap.channel.ChannelStatus.AUDIO_ONLY_BLOCKED ||
+ s.channelStatus == hcap.channel.ChannelStatus.VIDEO_ONLY_BLOCKED) {
+ hcap.channel.stopCurrentChannel({
+ "onSuccess": null,
+ "onFailure": function(f) {
+ console.log("onFailure : errorMessage = " + f.errorMessage);
+ }
+ });
+ }
+ },
+ "onFailure": function(f) {
+ console.log("onFailure : errorMessage = " + f.errorMessage);
+ }
+ });
+ },
+
+
+ ChannelSetup: function(_type, _param) {
+ if (g_media.pipeline == true) {
+ g_media.pipeline = false;
+ __hcapfxn_media_shutdown().then(function() {
+ setTimeout(__hcapfxn_play_channel(_type, _param), 500);
+ }).catch(function(err) {
+ console.log(err); // Error: Request is failed
+ });
+ } else {
+ __hcapfxn_play_channel(_type, _param);
+ }
+ },
+
+ siAppAuth: function(sz_app_name, app_token, _en_show_msg) {
+ let app_id = null;
+ if (sz_app_name == "netflix") {
+ app_id = "244115188075859013";
+ }
+
+ if (app_id && app_token) {
+ hcap.application.RegisterSIApplicationList({
+ "tokenList": [{ "id": "netflix", "token": app_token }, ],
+ "onSuccess": function(s) {
+ if (_en_show_msg == true) {
+ console.log("register Success!");
+ HotelTV.hcap.PreAppGetInfo(true);
+ }
+ },
+ "onFailure": function(f) {
+ console.log("register Failed! reason : " + f.errorMessage);
+ }
+ });
+ }
+ },
+
+ PreAppGetInfo: function(_en_show_msg) {
+ if (g_hcap_info.preapp == null) {
+ hcap.preloadedApplication.getPreloadedApplicationList({
+ "onSuccess": function(s) {
+ if (_en_show_msg == true) {
+ console.log("onSuccess : list length = " + s.list.length);
+ for (var i = 0; i < s.list.length; i++) {
+ console.log(
+ "list[" + i + "].id = " + s.list[i].id +
+ "list[" + i + "].title = " + s.list[i].title +
+ "list[" + i + "].iconFilePath = " + s.list[i].iconFilePath
+ );
+ }
+ }
+ if (s.result == true) {
+ g_hcap_info.preapp = s.list;
+ }
+ },
+ "onFailure": function(f) {
+ console.log("onFailure : errorMessage = " + f.errorMessage);
+ }
+ });
+ }
+ },
+
+ LaunchPreApp: function(_name, _param) {
+ if (g_hcap_info.preapp != null) {
+ if (_name == "youtube") {
+ for (const [key, item] of Object.entries(g_hcap_info.preapp)) {
+ if (item.title == 'YouTube') {
+ hcap.preloadedApplication.launchPreloadedApplication({
+ "id": item.id, // YOUTUBE
+ "onSuccess": function() {
+ console.log("onSuccess");
+ },
+ "onFailure": function(f) {
+ console.log("onFailure : errorMessage = " + f.errorMessage);
+ }
+ });
+ }
+ }
+ } else if (_name == "netflix") {
+ for (const [key, item] of Object.entries(g_hcap_info.preapp)) {
+ if (item.title == 'Netflix') {
+ hcap.preloadedApplication.launchPreloadedApplication({
+ "id": item.id, // NETFLIX
+ "parameter": "{'params': {'hotel_id':'CENTIRM-Demo','launcher_version':'1.0'}",
+ "onSuccess": function() {
+ console.log("onSuccess");
+ },
+ "onFailure": function(f) {
+ console.log("onFailure : errorMessage = " + f.errorMessage);
+ }
+ });
+ }
+ }
+ } else if (_name == "SCREENSHARE") {
+ for (const [key, item] of Object.entries(g_hcap_info.preapp)) {
+ if (item.id == '144115188075855880') {
+ hcap.preloadedApplication.launchPreloadedApplication({
+ "id": item.id, // SCREEN SHARE
+ "onSuccess": function() {
+ console.log("onSuccess");
+ },
+ "onFailure": function(f) {
+ console.log("onFailure : errorMessage = " + f.errorMessage);
+ }
+ });
+ }
+ }
+ } else if (_name == "BLUETOOTHAUDIO") {
+ for (const [key, item] of Object.entries(g_hcap_info.preapp)) {
+ if (item.id == '244115188075859015') {
+ hcap.preloadedApplication.launchPreloadedApplication({
+ "id": item.id, // SCREEN SHARE
+ "onSuccess": function() {
+ console.log("onSuccess");
+ },
+ "onFailure": function(f) {
+ console.log("onFailure : errorMessage = " + f.errorMessage);
+ }
+ });
+ }
+ }
+ }
+ } else {
+ console.log("Preloaded Application doesn't exist");
+ }
+ },
+
+ SetPlatformLanguage: function(_param) {
+ const _pmFxnArProperty = [];
+
+ if (_param == "ko-KR") {
+ _pmFxnArProperty.push(__hcapfxn_set_property('language', "ko"));
+ } else {
+ _pmFxnArProperty.push(__hcapfxn_set_property('language', "en"));
+ }
+
+ Promise.all(_pmFxnArProperty)
+ .then(_ret => {
+ let _devinfo = HotelTV.devinfo;
+ for (let i = 0; i < _ret.length; i++) {
+ let _dic_item = _ret[i];
+ if (_dic_item.value != null) {
+ _devinfo[_dic_item.key] = _dic_item.value;
+ } else {
+ console.log(`ERROR::>Item[${_dic_item.key}] is NULL::>`);
+ }
+ //console.log(`Item[${_dic_item.key}] ::> ${_dic_item.value}`);
+ };
+ });
+ },
+
+ SetSoftAp: function(_param) {
+ return new Promise((resolve, reject) => {
+ const _pmFxnArProperty = [];
+ _pmFxnArProperty.push(__hcapfxn_get_property("soft_ap"));
+ _pmFxnArProperty.push(__hcapfxn_get_property("soft_ap_ui"));
+
+ if (_param.enable == true) {
+ let _devinfo = HotelTV.devinfo;
+ // // TV NAME(SSID)
+ // if (_devinfo["tv_name"] !== _param.ssid) {
+ // _pmFxnArProperty.push(__hcapfxn_set_property('tv_name', _param.ssid));
+ // _pmFxnArProperty.push(__hcapfxn_set_property('soft_ap_password', _param.password));
+ // }
+
+ // TV NAME(SSID)
+ if (_devinfo["tv_name"] !== _param.ssid) {
+ _pmFxnArProperty.push(__hcapfxn_set_property('tv_name', _param.ssid));
+ }
+
+ if (_param.password) {
+ _pmFxnArProperty.push(__hcapfxn_set_property('soft_ap_password', _param.password));
+ }
+ }
+
+ Promise.all(_pmFxnArProperty)
+ .then(_ret => {
+ let _devinfo = HotelTV.devinfo;
+ for (let i = 0; i < _ret.length; i++) {
+ let _dic_item = _ret[i];
+ if (_dic_item.value != null) {
+ _devinfo[_dic_item.key] = _dic_item.value;
+ console.log(`Item[${_dic_item.key}] ::> ${_dic_item.value}`);
+ } else {
+ console.log(`ERROR::>Item[${_dic_item.key}] is NULL::>`);
+ }
+ //console.log(`Item[${_dic_item.key}] ::> ${_dic_item.value}`);
+ };
+
+ if (_param.enable == true) {
+ if (_devinfo["soft_ap_ui"] != 1) {
+ console.log("TRY TO TURN ON::> SoftAP");
+ __hcapfxn_set_property('soft_ap_ui', 1).then(_result => {
+ if (_devinfo["soft_ap"] != 1) {
+ __hcapfxn_set_property('soft_ap', 1).then(_result => {
+ console.log("TRY TO TURN ONED::> SoftAP");
+ });
+ }
+ });
+ }
+ } else {
+ if (_devinfo["soft_ap"] != 0) {
+ console.log("TRY TO TURN OFF::> SoftAP");
+ __hcapfxn_set_property('soft_ap', 0).then(_result => {
+ if (_devinfo["soft_ap_ui"] != 0) {
+ __hcapfxn_set_property('soft_ap_ui', 0).then(_result => {
+ console.log("TRY TO TURN OFFED::> SoftAP");
+ });
+ }
+ });
+ }
+ }
+ });
+ });
+ },
+
+ GetDeviceUsage: function() {
+ return new Promise((resolve, reject) => {
+ const _pmFxnArProperty = [];
+ _pmFxnArProperty.push(__hcapfxn_get_cpuUsage());
+ _pmFxnArProperty.push(__hcapfxn_get_memUsage());
+ Promise.all(_pmFxnArProperty)
+ .then(_ret => {
+ resolve({ "cpu": _ret[0].value, "mem": _ret[1].value });
+ }).catch(_err => {
+ resolve({ "cpu": -1, "mem": -1 });
+ });
+ });
+ },
+
+ GetUptime: function() {
+ let _devinfo = HotelTV.devinfo;
+ __hcapfxn_get_cpuTime(function(_uptime) {
+ _devinfo['uptime'] = _uptime;
+ });
+ },
+
+ GetScrshot: function() {
+ hcap.file.getUsbStorageList({
+ "onSuccess": function(s) {
+ console.log("onSuccess : list length = " + s.list.length);
+ for (var i = 0; i < s.list.length; i++) {
+ console.log(
+ "[" + i + "].name = " + s.list[i].name +
+ "[" + i + "].displayName = " + s.list[i].displayName +
+ "[" + i + "].mountPoint = " + s.list[i].mountPoint +
+ "[" + i + "].status = " + s.list[i].status +
+ "[" + i + "].filesystemStatus = " + s.list[i].filesystemStatus +
+ "[" + i + "].totalSize = " + s.list[i].totalSize +
+ "[" + i + "].freeSize = " + s.list[i].freeSize
+ );
+ }
+ },
+ "onFailure": function(f) {
+ console.log("onFailure : errorMessage = " + f.errorMessage);
+ }
+ });
+
+ hcap.system.requestScreenCaptureImage({
+ "onSuccess": function() {
+ console.log("onSuccess");
+ hcap.system.getScreenCaptureImage({
+ "onSuccess": function(s) {
+ console.log("onSuccess : uri = " + s.uri);
+ hcap.file.downloadFileToUsb({
+ "uri": s.uri,
+ "path": "/tmp/usb/sda/sda1/youtube_s3.png",
+ "onSuccess": function() {
+ console.log("onSuccess");
+ },
+ "onFailure": function(f) {
+ console.log("onFailure : errorMessage = " + f.errorMessage);
+ }
+ });
+ },
+ "onFailure": function(f) {
+ console.log("onFailure : errorMessage = " + f.errorMessage);
+ }
+ });
+ },
+ "onFailure": function(f) {
+ console.log("onFailure : errorMessage = " + f.errorMessage);
+ }
+ });
+ },
+
+ Test: function() {
+ console.log("Test Start....");
+
+
+ // hcap.bluetooth.getBluetoothSoundSync({
+ // "onSuccess": function(param) {
+ // console.log("onSuccess : bluetooth sound sync = " + param.enable);
+ // },
+ // "onFailure": function(f) {
+ // console.log("onFailure : errorMessage = " + f.errorMessage);
+ // }
+ // });
+
+ // hcap.externalinput.getExternalInputList({
+ // "onSuccess": function(s) {
+ // console.log("onSuccess : list length = " + s.list.length);
+ // for (var i = 0; i < s.list.length; i++) {
+ // console.log("(" + s.list[i].type + "," + s.list[i].index + "," + s.list[i].name + ")");
+ // }
+ // },
+ // "onFailure": function(f) {
+ // console.log("onFailure : errorMessage = " + f.errorMessage);
+ // }
+ // });
+
+ // // 외부 입력(HDMI, 등) 이벤트 리스너
+ // document.addEventListener(
+ // "external_input_changed",
+ // function() {
+ // console.log("Event 'external_input_changed' is received.");
+ // },
+ // false
+ // );
+
+ // 프리 인스톨디드 어플리케이션 실행
+ // hcap.preloadedApplication.getPreloadedApplicationList({
+ // "onSuccess": function(s) {
+ // console.log("onSuccess : list length = " + s.list.length);
+ // for (var i = 0; i < s.list.length; i++) {
+ // console.log(
+ // "list[" + i + "].id = " + s.list[i].id +
+ // "list[" + i + "].title = " + s.list[i].title +
+ // "list[" + i + "].iconFilePath = " + s.list[i].iconFilePath
+ // );
+ // }
+ // },
+ // "onFailure": function(f) {
+ // console.log("onFailure : errorMessage = " + f.errorMessage);
+ // }
+ // });
+
+
+ // hcap.preloadedApplication.launchPreloadedApplication({
+ // "id": "244115188075859015", // BLUETOOTH
+ // "onSuccess": function() {
+ // console.log("onSuccess");
+ // },
+ // "onFailure": function(f) {
+ // console.log("onFailure : errorMessage = " + f.errorMessage);
+ // }
+ // });
+
+ // hcap.preloadedApplication.launchPreloadedApplication({
+ // "id": "144115188075859002", // YOUTUBE
+ // "onSuccess": function() {
+ // console.log("onSuccess");
+ // },
+ // "onFailure": function(f) {
+ // console.log("onFailure : errorMessage = " + f.errorMessage);
+ // }
+ // });
+
+ // hcap.preloadedApplication.launchPreloadedApplication({
+ // "id": "144115188075859002", // NK-Browser
+ // "onSuccess": function() {
+ // console.log("onSuccess");
+ // },
+ // "onFailure": function(f) {
+ // console.log("onFailure : errorMessage = " + f.errorMessage);
+ // }
+ // });
+
+
+
+ // hcap.preloadedApplication.launchPreloadedApplication({
+ // "id": "244115188075859022", // NK-Browser
+ // "parameters": "{'params':{'target': 'https://www.netflix.com/kr/login'}}",
+ // "onSuccess": function() {
+ // console.log("onSuccess");
+ // },
+ // "onFailure": function(f) {
+ // console.log("onFailure : errorMessage = " + f.errorMessage);
+ // }
+ // });
+
+
+
+ // 음성 인식 관련
+ // hcap.speech.getSpeechRecognition({
+ // "onSuccess": function(param) {
+ // console.log("onSuccess : get speech recognition = " + param.enable);
+
+ // if (param.enable == false) {
+ // hcap.speech.setSpeechRecognition({
+ // "enable": true,
+ // "onSuccess": function() {
+ // console.log("onSuccess");
+ // },
+ // "onFailure": function(f) {
+ // console.log("onFailure : errorMessage = " + f.errorMessage);
+ // }
+ // });
+ // }
+ // },
+ // "onFailure": function(f) {
+ // console.log("onFailure : errorMessage = " + f.errorMessage);
+ // }
+ // });
+
+ // document.addEventListener(
+ // "speech_to_text_status_changed",
+ // function(param) {
+ // // {String} param.status - "processing" : STT is processing. "ready" : STT is completed.
+ // // {String} param.actionData - STT intent parameter when STT status is changed from "processing" to "ready".
+ // // {String} param.serviceType - STT result category when STT status is changed from "processing" to "ready".
+ // // {String} param.actionType - STT result intent when STT status is changed from "processing" to "ready".
+ // // {String} param.userUtterance - STT result text when STT status is changed from "processing" to "ready".
+ // console.log(
+ // "Event 'speech_to_text_status_changed' is received.\n" +
+ // "status = " + param.status +
+ // "action data = " + param.actionData +
+ // "service type = " + param.serviceType +
+ // "action type = " + param.actionType +
+ // "user utterance = " + param.userUtterance
+ // );
+ // },
+ // false
+ // );
+ // hcap.channel.stopCurrentChannel({
+ // "onSuccess": function() {
+ // console.log("onSuccess");
+ // },
+ // "onFailure": function(f) {
+ // console.log("onFailure : errorMessage = " + f.errorMessage);
+ // }
+ // });
+
+
+ // // 채널 관련 API
+ // hcap.channel.getChannelMap({
+ // "onSuccess": function(s) {
+ // console.log("onSuccess : list length = " + s.list.length);
+ // for (var i = 0; i < s.list.length; i++) {
+ // console.log(
+ // "[" + i + "].img_url2 = " + s.list[i].img_url2 +
+ // "[" + i + "].img_url = " + s.list[i].img_url +
+ // "[" + i + "].short_cut = " + s.list[i].short_cut +
+ // "[" + i + "].channel_type = " + s.list[i].channel_type +
+ // "[" + i + "].channel_mode_id = " + s.list[i].channel_mode_id +
+ // "[" + i + "].channel_number = " + s.list[i].channel_number +
+ // "[" + i + "].channel_name = " + s.list[i].channel_name
+ // );
+ // }
+ // },
+ // "onFailure": function(f) {
+ // console.log("onFailure : errorMessage = " + f.errorMessage);
+ // }
+ // });
+
+
+ // hcap.video.getVideoSize({
+ // "onSuccess": function(s) {
+ // console.log("onSuccess : " +
+ // "\n x = " + s.x +
+ // "\n y = " + s.y +
+ // "\n width = " + s.width +
+ // "\n height = " + s.height);
+ // },
+ // "onFailure": function(f) {
+ // console.log("onFailure : errorMessage = " + f.errorMessage);
+ // }
+ // });
+ },
+ }
+})();
\ No newline at end of file
diff --git a/procentric/application/lib/hoteltv.js b/procentric/application/lib/hoteltv.js
new file mode 100755
index 0000000..f8c778d
--- /dev/null
+++ b/procentric/application/lib/hoteltv.js
@@ -0,0 +1,558 @@
+/**
+ * Copyright (c) 2020
+ *
+ * CENTIRM HotelTV Core javascript.
+ *
+ * @summary short description for the file
+ * @author Joel
+ *
+ * Created at : 2020-11-26 02:21:56
+ * Last modified : 2020-11-26 15:31:40
+ */
+
+
+var HotelTV = HotelTV || {
+ 'devinfo': {},
+ 'svrinfo': {},
+ 'services': {},
+ 'settings': {},
+ 'hotelinfo': {},
+ 'guestinfo': {},
+ 'opening': {},
+ 'flight': {},
+ 'weather': {},
+ 'epg': {},
+ 'news': {},
+ 'tvguide': {},
+ 'message': {},
+ 'translation': {},
+ 'state': {
+ 'lang': 'kr',
+ 'menu': {
+ 'stage': null,
+ 'main': {
+ 'cnt': 0,
+ 'cur': null,
+ 'prev': null,
+ },
+ },
+ 'media': {
+ 'playing': false,
+ },
+ 'hotkey': {
+ "mm": {}
+ },
+ 'token': null
+ },
+ 'carts': {
+ 'amenity': {
+
+ },
+ 'roomservice': {
+
+ }
+ },
+ 'orders': {
+ 'amenity': {
+
+ },
+ 'roomservice': {
+
+ }
+ },
+ 'dbginfo': {
+ 'en': false,
+ 'emulator': false, //PC 브라우저를 이용할때, true로 설정, 타겟 셋트에서는 false로 설정할것
+ 'hcap_ipc': false,
+ 'output': 'osd'
+ },
+ 'media_hndl': null,
+};
+
+
+
+HotelTV.namespace = function(ns_string) {
+ var parts = ns_string.split('.'),
+ parent = HotelTV,
+ i; // 처음에 중복되는 전역 객체명은 제거한다.
+ if (parts[0] == 'HotelTV') {
+ parts = parts.slice(1);
+ }
+ for (i = 0; i < parts.length; i += 1) {
+ if (typeof parent[parts[i]] == 'undefined') {
+ parent[parts[i]] = {};
+ }
+ parent = parent[parts[i]];
+ }
+ return parent;
+};
+
+
+
+
+//// 비공개 매써드
+/**
+ * HCAP Wrapper Function::> Get ProCentric Server Info(Realted HCAP API:hcap.system.getHotelMode)
+ * @param {string} sz_key property key name.
+ * @param {callback} callback is callback object
+ */
+function __fxn_Set_DebugOpt() {
+ HotelTV.dbginfo['en'] = true;
+ HotelTV.dbginfo['output'] = 'native';
+
+ HotelTV.hcap.Init();
+
+ /** Develop Mode definitions */
+ console.log("OPT" + navigator.appVersion);
+ if (navigator.appVersion.includes("Web0S") == true) {
+ HotelTV.dbginfo['emulator'] = false;
+ } else {
+ HotelTV.dbginfo['emulator'] = true;
+ }
+
+ if (HotelTV.dbginfo['output'] == 'osd') {
+ if (HotelTV.dbginfo['en'] == true) {
+ (function() {
+ var old = console.log;
+ var logger = document.getElementById('debugwin');
+ var dateNow = new Date();
+ var hours = dateNow.getHours();
+ var minutes = dateNow.getMinutes();
+ var seconds = dateNow.getSeconds();
+ if (hours < 10) {
+ hours = "0" + hours;
+ }
+ if (minutes < 10) {
+ minutes = "0" + minutes;
+ }
+ if (seconds < 10) {
+ seconds = "0" + seconds;
+ }
+ console.log = function(logmsg) {
+ var _dispMsg = hours + ":" + minutes + ":" + seconds + "-> ";
+ if (typeof logmsg == 'object') {
+ _dispMsg += (JSON && JSON.stringify ? JSON.stringify(logmsg) : logmsg) + '
';
+ } else {
+ _dispMsg += logmsg + '
';
+ }
+ _dispMsg += logger.innerHTML;
+
+ logger.innerHTML = _dispMsg;
+ }
+ })();
+ }
+ } else {
+ /** Set HCAP Debug Options */
+ if (HotelTV.dbginfo['emulator'] == false) {
+ //Enable/Disable browser debug mode
+ HotelTV.hcap.SetBrowserDebug(HotelTV.dbginfo['hcap_ipc'], HotelTV.dbginfo['en']);
+ } else {
+ //Below for Non WebOS
+ }
+ }
+};
+
+
+
+
+HotelTV.Init = async function() {
+ console.log("Start Initialization:: ");
+ //STEP#01::> Shutdown Channel
+ HotelTV.hcap.ChannelShutDown();
+
+ //SETP#02::> Set Debug Options
+ __fxn_Set_DebugOpt();
+
+ //STEP#03::> Get Device Info
+ HotelTV.ui_utils.SetBusy(true);
+ try {
+ await HotelTV.hcap.GetDevInfo();
+ //await HotelTV.hcap.ShowDevInfo();
+ } catch (_error) {
+ console.log("Fail to get device information");
+ }
+
+ //STEP#04::> API Module INIT
+ await HotelTV.api.Init(HotelTV.svrinfo.ipaddr, HotelTV.svrinfo.port, HotelTV.devinfo.model_name.substring(2, HotelTV.devinfo.model_name.length - 1), HotelTV.devinfo.serial_number);
+
+ try {
+ let __apiRet = await HotelTV.api.CheckRegistration();
+ HotelTV.state['registration'] = await HotelTV.api.CheckRegistration();
+ } catch (_error) {
+ console.log("Display Error page for check registration");
+ }
+
+ if (HotelTV.state['registration'].registered != true) {
+ console.log("Show up and unregistered device");
+ }
+
+ //STEP05::> CHECK HOTELTV LICENSE
+ if (HotelTV.state['registration'].license == 'hotel-full') {
+ // FULL LICENSE MODE
+ try {
+ HotelTV.settings = await HotelTV.api.GetSettings();
+ let need_reboot = await HotelTV.hcap.SetDevice(HotelTV.settings);
+ if (need_reboot == true) {
+ console.log("System Need to Reboot");
+ HotelTV.ui_utils.SetBusy(false);
+ HotelTV.ui_utils.ShowErrMsg(true, "", "");
+ setTimeout(HotelTV.hcap.Reboot(), 3000);
+ return;
+ }
+ } catch (_error) {
+ console.log("Display Error page for get stttings");
+ }
+
+ try {
+ HotelTV.hotelinfo = await HotelTV.api.GetHotelInfo();
+ } catch (_error) {
+ console.log("Display Error page for get hotel info");
+ }
+
+ try {
+ HotelTV.guestinfo = await HotelTV.api.GetGuestInfo();
+ } catch (_error) {
+ console.log("Display Error page for get Guest info");
+ }
+
+ try {
+ HotelTV.opening = await HotelTV.api.GetOpeningCtz();
+ } catch (_error) {
+ console.log("Display Error page for get Opening Contents");
+ }
+
+ try {
+ HotelTV.weather = await HotelTV.api.GetWeather();
+ } catch (_error) {
+ console.log("Display Error page for get Weather info");
+ }
+
+ try {
+ HotelTV.flight = await HotelTV.api.GetFlight();
+ } catch (_error) {
+ console.log("Display Error page for get flight info");
+ }
+
+ try {
+ HotelTV.tvguide = await HotelTV.api.GetProgramCtz();
+ } catch (_error) {
+ console.log("Display Error page for get tvguide info");
+ }
+
+ try {
+ HotelTV.epg = await HotelTV.api.GetEpg();
+ } catch (_error) {
+ console.log("Display Error page for get epg info");
+ }
+
+ try {
+ HotelTV.news = await HotelTV.api.GetNews();
+ } catch (_error) {
+ console.log("Display Error page for get news info");
+ }
+
+ try {
+ HotelTV.message = await HotelTV.api.GetMessage();
+ } catch (_error) {
+ console.log("Display Error page for get news info");
+ }
+
+ try {
+ HotelTV.translation = await HotelTV.api.GetTranslation();
+ } catch (_error) {
+ console.log("Display Error page for get translation info");
+ }
+
+
+ //Save to Session
+ sessionStorage.setItem("devinfo", JSON.stringify(HotelTV.devinfo));
+ sessionStorage.setItem("svrinfo", JSON.stringify(HotelTV.svrinfo));
+ sessionStorage.setItem("settings", JSON.stringify(HotelTV.settings));
+ sessionStorage.setItem("state", JSON.stringify(HotelTV.state));
+ sessionStorage.setItem("hotelinfo", JSON.stringify(HotelTV.hotelinfo));
+ sessionStorage.setItem("guestinfo", JSON.stringify(HotelTV.guestinfo));
+ sessionStorage.setItem("opening", JSON.stringify(HotelTV.opening));
+ sessionStorage.setItem("flight", JSON.stringify(HotelTV.flight));
+ sessionStorage.setItem("weather", JSON.stringify(HotelTV.weather));
+ sessionStorage.setItem("tvguide", JSON.stringify(HotelTV.tvguide));
+ sessionStorage.setItem("news", JSON.stringify(HotelTV.news));
+ sessionStorage.setItem("message", JSON.stringify(HotelTV.message));
+ sessionStorage.setItem("translation", JSON.stringify(HotelTV.translation));
+
+ //Now Switch Over Welcome page
+ if (HotelTV.opening != null) {
+ $(".startup").fadeOut(1000, function() {
+ window.location.replace('./wellcome.html');
+ });
+ } else {
+ if (HotelTV.state['registration'].license == 'hotel-full') {
+ setTimeout(function() {
+ window.location.replace('./app_hoteltv_full.html');
+ }, 1000);
+ }
+ }
+ } else {
+ console.log("Display Error page for invalid license type.");
+ }
+ console.log("Initialization:: Done");
+ HotelTV.ui_utils.SetBusy(false);
+
+ SpatialNavigation.init();
+};
+
+HotelTV.LoadWelCome = async function() {
+ HotelTV.devinfo = await JSON.parse(sessionStorage.getItem("devinfo"));
+ HotelTV.svrinfo = await JSON.parse(sessionStorage.getItem("svrinfo"));
+ HotelTV.state = await JSON.parse(sessionStorage.getItem("state"));
+ //STEP#03:API Module INIT
+ await HotelTV.api.Init(HotelTV.svrinfo.ipaddr, HotelTV.svrinfo.port, HotelTV.devinfo.model_name.substring(2, HotelTV.devinfo.model_name.length - 1), HotelTV.devinfo.serial_number);
+ HotelTV.settings = await JSON.parse(sessionStorage.getItem("settings"));
+ HotelTV.guestinfo = await JSON.parse(sessionStorage.getItem("guestinfo"));
+ HotelTV.hotelinfo = await JSON.parse(sessionStorage.getItem("hotelinfo"));
+ HotelTV.opening = await JSON.parse(sessionStorage.getItem("opening"));
+ HotelTV.tvguide = await JSON.parse(sessionStorage.getItem("tvguide"));
+ try {
+ HotelTV.services = await HotelTV.api.GetServiceInfo();
+ sessionStorage.setItem("services", JSON.stringify(HotelTV.services));
+ } catch (_error) {
+ console.log("Display Error page for get service info");
+ }
+ //HotelTV.translation = await JSON.parse(sessionStorage.getItem("translation"));
+ try {
+ HotelTV.translation = await HotelTV.api.GetTranslation();
+ } catch (_error) {
+ console.log("Display Error page for get translation info");
+ }
+
+
+
+ //Set checkined guest language
+ HotelTV.state.lang = HotelTV.guestinfo.language;
+
+ let _res = HotelTV.devinfo.display_resolution.split("x");
+ HotelTV.ui_welcome.Init(_res[0], _res[1]);
+
+ //await HotelTV.hcap.ShowDevInfo();
+ HotelTV.ui_welcome.Show();
+}
+
+HotelTV.UnloadWelCome = async function() {
+ sessionStorage.setItem("state", JSON.stringify(HotelTV.state));
+ HotelTV.ui_welcome.Close();
+ if (HotelTV.state['registration'].license == 'hotel-full') {
+ setTimeout(function() {
+ window.location.replace('./app_hoteltv_full.html');
+ }, 1000);
+ }
+}
+
+
+HotelTV.LoadAppFull = async function() {
+ HotelTV.ui_utils.SetBusy(true);
+
+ //STEP#01: Load session info
+ HotelTV.devinfo = await JSON.parse(sessionStorage.getItem("devinfo"));
+ HotelTV.svrinfo = await JSON.parse(sessionStorage.getItem("svrinfo"));
+ HotelTV.services = await JSON.parse(sessionStorage.getItem("services"));
+ HotelTV.state = await JSON.parse(sessionStorage.getItem("state"));
+
+ //STEP#02: Init HotelTV API
+ await HotelTV.api.Init(HotelTV.svrinfo.ipaddr, HotelTV.svrinfo.port, HotelTV.devinfo.model_name.substring(2, HotelTV.devinfo.model_name.length - 1), HotelTV.devinfo.serial_number);
+ HotelTV.settings = await JSON.parse(sessionStorage.getItem("settings"));
+ HotelTV.guestinfo = await JSON.parse(sessionStorage.getItem("guestinfo"));
+ HotelTV.hotelinfo = await JSON.parse(sessionStorage.getItem("hotelinfo"));
+ HotelTV.weather = await JSON.parse(sessionStorage.getItem("weather"));
+ HotelTV.opening = await JSON.parse(sessionStorage.getItem("opening"));
+ HotelTV.tvguide = await JSON.parse(sessionStorage.getItem("tvguide"));
+ HotelTV.flight = await JSON.parse(sessionStorage.getItem("flight"));
+ HotelTV.news = await JSON.parse(sessionStorage.getItem("news"));
+ HotelTV.message = await JSON.parse(sessionStorage.getItem("message"));
+ //HotelTV.epg = await JSON.parse(sessionStorage.getItem("epg"));
+
+ try {
+ HotelTV.carts.amenity = await HotelTV.api.GetAmenityCarts(null);
+ } catch (_error) {
+ console.log("Display Error page for get amenity carts info");
+ }
+
+ try {
+ HotelTV.carts.roomservice = await HotelTV.api.GetRoomserviceCarts();
+ } catch (_error) {
+ console.log("Display Error page for get roomservicec carts info");
+ }
+
+
+ try {
+ HotelTV.orders.amenity = await HotelTV.api.GetAmenityOrders(null);
+ } catch (_error) {
+ console.log("Display Error page for get amenity order info");
+ }
+
+ try {
+ HotelTV.orders.roomservice = await HotelTV.api.GetRoomserviceOrders(null);
+ } catch (_error) {
+ console.log("Display Error page for get roomservice order info");
+ }
+
+
+ try {
+ HotelTV.translation = await HotelTV.api.GetTranslation();
+ } catch (_error) {
+ console.log("Display Error page for get translation info");
+ }
+ //HotelTV.translation = await JSON.parse(sessionStorage.getItem("translation"));
+
+
+ //STEP#03: INIT HCAP for HotelTV FullAPP
+ try {
+ let siAppToken = null;
+ let siAppName = null;
+ // siApp Token Authentication
+ let _progam = HotelTV.tvguide.program;
+ for (let _i = 1; _i <= _progam.length; _i++) {
+ if (_progam[_i].type == "application" && _progam[_i].service == "netflix") {
+ siAppToken = await HotelTV.api.DownloadData(_progam[_i].license.file.download);
+ siAppName = _progam[_i].service;
+ //siAppToken = _progam[_i].service;
+
+ if (siAppName && siAppToken) {
+ HotelTV.hcap.siAppAuth(siAppName, siAppToken, false);
+ }
+ }
+ }
+ } catch (_error) {
+ console.log("Display Error page for get siApp Auth");
+ }
+
+ //STEP#05: Set Display size
+ let _res = HotelTV.devinfo.display_resolution.split("x");
+ HotelTV.ui_appfull.Init(_res[0], _res[1]);
+ HotelTV.hcap.PreAppGetInfo(false);
+
+ //STEP#06; Show UI
+ //await HotelTV.hcap.ShowDevInfo();
+ HotelTV.ui_appfull.Show();
+
+ //STEP#06 Register Service web worker
+ if (window.SharedWorker) {
+ const myWorker = new SharedWorker("./lib/hoteltv.service.js");
+
+ myWorker.port.postMessage({
+ 'cmd': "start_service",
+ "param": {
+ "token": HotelTV.state.token,
+ "dev_family": HotelTV.devinfo.model_name.substring(2, HotelTV.devinfo.model_name.length - 1),
+ "dev_snum": HotelTV.devinfo.serial_number,
+ "svrinfo": HotelTV.svrinfo,
+ },
+ });
+
+
+
+ myWorker.port.onmessage = function(e) {
+ let recvMsg = e.data;
+ //console.log(`Recv Msg[${recvMsg.event}]::> ${recvMsg.ret} ::> ${recvMsg.data}`);
+ //console.log(`Recv Msg[${recvMsg.event}]::> ${recvMsg.ret}`);
+
+ // if (recvMsg.event == "update_epg") {
+ // if (recvMsg.ret === "OK") {
+ // HotelTV.epg = recvMsg.data;
+ // HotelTV.ui_appfull.UpdateEpg();
+ // }
+ // } else if (recvMsg.event == "update_news") {
+ // if (recvMsg.ret === "OK") {
+ // HotelTV.news = recvMsg.data;
+ // }
+ // } else if (recvMsg.event == "update_flight") {
+ // if (recvMsg.ret === "OK") {
+ // let x2js = new X2JS();
+ // _rspJson = x2js.xml2json($.parseXML(recvMsg.data));
+ // HotelTV.flight = { "count": Number(_rspJson.response.body.totalCount), "info": _rspJson.response.body.items.item };
+ // }
+ // } else if (recvMsg.event == "update_weather") {
+
+ // } else if (recvMsg.event == "update_report") {
+ // // HotelTV.hcap.GetUptime();
+ // // HotelTV.hcap.GetDeviceUsage().then(_usage => {
+ // // //console.log(`USAGE::> CPU[${_usage.cpu}%] RAM[${_usage.mem}%]`);
+ // // //HotelTV.api.ReportBrief(HotelTV.devinfo, HotelTV.guestinfo, _usage);
+ // // });
+ // } else if (recvMsg.event == "mqtt_events") {
+ // console.log(`MQTTMSG::> ${recvMsg.data}`);
+ // }
+ }
+ } else {
+ console.log('Your browser doesn\'t support web workers.')
+ }
+
+ //STEP#07 MQTT Service
+ if (HotelTV.services) {
+ if (HotelTV.services.mqtt) {
+ let _mqttSvcInfo = HotelTV.services.mqtt;
+
+ if (_mqttSvcInfo.protocol == "ws") {
+ var client = mqtt.connect(
+ //'ws://' + HotelTV.svrinfo.ipaddr + ':9001',
+ 'ws://' + _mqttSvcInfo.host + ':' + _mqttSvcInfo.port, {
+ clean: true, // retain session
+ connectTimeout: 4000, // Timeout period
+ username: _mqttSvcInfo.username,
+ password: _mqttSvcInfo.password,
+ clientId: 'mqtt_sid_' + HotelTV.devinfo.serial_number.substring(0, 12)
+ }
+ );
+
+ client.on('connect', function() {
+ // let sz_topic = ['ctlxb0_' + HotelTV.devinfo.serial_number + '/topic', 'ctlxb0_all/topic'];
+
+ // client.subscribe(sz_topic[0], function(err) {
+ // if (err) {
+ // console.log(`Fail to subscribe::TOPIC[${sz_topic[0]}]`);
+ // }
+ // });
+
+ // client.subscribe(sz_topic[1], function(err) {
+ // if (err) {
+ // console.log(`Fail to subscribe::TOPIC[${sz_topic[1]}]`);
+ // }
+ // })
+
+ client.subscribe(_mqttSvcInfo.topic, function(err) {
+ if (err) {
+ console.log(`Fail to subscribe::TOPIC[${_mqttSvcInfo.topic}]`);
+ } else {
+ console.log(`Success to subscribe::TOPIC[${_mqttSvcInfo.topic}]`);
+ }
+ });
+ })
+
+ client.on('message', function(topic, message) {
+ let szMsg = message.toString();
+ HotelTV.ui_appfull.MqttEvent(szMsg);
+ //MQTT메시지 종료 하려면 아래 end호출
+ //client.end()
+ })
+
+ client.on('error', function(error) {
+ // message is Buffer
+ console.log(error.toString());
+ //client.end()
+ })
+ }
+ }
+ }
+
+
+ //
+ HotelTV.hcap.Test();
+}
+
+HotelTV.UnloadAppFull = async function() {
+
+}
+
+
+HotelTV.Deinit = function() {
+ console.log("Start De-Initialization:: ");
+ //HotelTV.service.Deinit();
+}
\ No newline at end of file
diff --git a/procentric/application/lib/hoteltv.service.js b/procentric/application/lib/hoteltv.service.js
new file mode 100755
index 0000000..7f93fe4
--- /dev/null
+++ b/procentric/application/lib/hoteltv.service.js
@@ -0,0 +1,291 @@
+/**
+ * Copyright (c) 2020
+ *
+ * CENTIRM HotelTV Background service module javascript.
+ *
+ * @summary short description for the file
+ * @author Joel
+ *
+ * Created at : 2020-11-26 02:21:56
+ * Last modified : 2020-11-26 15:31:40
+ */
+// importScripts('./lib/hoteltv.js');
+// importScripts('./lib/hoteltv.api.js');
+
+const g_config = {};
+var g_port = null;
+var g_tmrHndl = null;
+var g_tm_prev = {
+ "news": null,
+ "epg": null,
+ "weather": null,
+ "flight": null,
+ "report": null,
+};
+
+//// 비공개 매써드
+/**
+ * API Wrapper Function::>
+ */
+function __svcfxn_get_base_url() {
+ var sz_base_url = "http://" + g_config.svrinfo.ipaddr + ":" + g_config.svrinfo.port;
+ return sz_base_url;
+}
+
+/**
+ * API Wrapper Function::>
+ * @param {string} api_type api type.
+ * @param {callback} callback is callback object
+ */
+function __svcfxn_get_api_url(api_type) {
+ var dic_api_url = {
+ "get_news": __svcfxn_get_base_url() + "/api/" + g_config.token.version + "/assets/" + g_config.dev_family + "/" + g_config.dev_snum + "/news",
+ "get_epg": __svcfxn_get_base_url() + "/api/" + g_config.token.version + "/assets/" + g_config.dev_family + "/" + g_config.dev_snum + "/epg",
+ "get_weather": __svcfxn_get_base_url() + "/api/" + g_config.token.version + "/assets/" + g_config.dev_family + "/" + g_config.dev_snum + "/weather",
+ "get_flight": __svcfxn_get_base_url() + "/api/" + g_config.token.version + "/assets/" + g_config.dev_family + "/" + g_config.dev_snum + "/flight",
+ }
+
+ if (api_type in dic_api_url) {
+ return dic_api_url[api_type];
+ }
+ return null;
+}
+
+/**
+ * API Wrapper Function::> HOTELTV API
+ * @param {string} sz_url is API URL
+ * @param {string} api_type is API TYPE
+ * @param {dictionary} dic_param is PARAMETERs
+ */
+function __svcfxn_CallCmsApi(sz_url, api_type, dic_param) {
+ return new Promise((resolve, reject) => {
+ let isPostMsg = false;
+ let xhr = new XMLHttpRequest();
+ let formData = new FormData();
+ let _ret = { type: api_type, error: true, reason: null, data: null };
+
+ //xhr.timeout = 500;
+ if (dic_param !== null) {
+ isPostMsg = true;
+ for (_key in dic_param) {
+ formData.append(_key.toString(), dic_param[_key]);
+ }
+ }
+
+ xhr.onload = function() {
+ if (xhr.status === 200 || xhr.status === 201) {
+ _ret.error = false;
+ _ret.data = xhr.response;
+ resolve(_ret);
+ } else {
+ reject(_ret);
+ }
+ };
+
+ xhr.ontimeout = function(e) {
+ // XMLHttpRequest timed out. Do something here.
+ _ret.reason = "TIMEOUT";
+ reject(_ret);
+ };
+
+ xhr.onerror = function() {
+ _ret.reason = "FATAL";
+ reject(_ret);
+ }
+
+
+ if (isPostMsg) {
+ //console.log("Given api url is POST message")
+ xhr.open('POST', sz_url);
+ xhr.setRequestHeader("Accept", "application/json");
+ xhr.setRequestHeader("Content-Type", "application/json;charset=UTF-8");
+ xhr.setRequestHeader("Authorization", "Bearer " + g_config.token.apikey);
+ xhr.send(formData); // 폼 데이터 객체 전송
+ } else {
+ //console.log("Given api url is GET message")
+ xhr.open('GET', sz_url, true);
+ xhr.setRequestHeader("Accept", "application/json");
+ xhr.setRequestHeader("Content-Type", "application/json;charset=UTF-8");
+ xhr.setRequestHeader("Authorization", "Bearer " + g_config.token.apikey);
+ xhr.send(null);
+ }
+ });
+}
+
+
+
+/**
+ * HCAP Wrapper Function::> Get Device Properties(Realted HCAP API:hcap.property.getProperty)
+ * @param {string} sz_key property key name.
+ * @param {callback} callback is callback object
+ */
+async function sworker_service(args) {
+ return new Promise((resolve, reject) => {
+ let _bNeed_Update = {
+ "epg": false,
+ "news": false,
+ "flight": false,
+ "weather": false,
+ "report": false,
+ };
+ let _tm_cur = new Date();
+
+ // CHECK EPG INFORMATION UPDATE
+ if (g_tm_prev.epg == null) {
+ g_tm_prev.epg = new Date();
+ _bNeed_Update.epg = true;
+ } else {
+ let _tm_diff_ms = _tm_cur.getTime() - g_tm_prev.epg.getTime();
+ let _tm_diff_s = Math.floor(_tm_diff_ms / 1000);
+
+ //EPG정보는 매 30분 마다 한번씩 업데이트
+ if (_tm_diff_s > 1800) {
+ //if (_tm_diff_s > 60) {
+ g_tm_prev.epg = _tm_cur;
+ _bNeed_Update.epg = true;
+ }
+ }
+
+ // CHECK NEWS INFORMATION UPDATE
+ if (g_tm_prev.news == null) {
+ g_tm_prev.news = new Date();
+ _bNeed_Update.news = true;
+ } else {
+ let _tm_diff_ms = _tm_cur.getTime() - g_tm_prev.news.getTime();
+ let _tm_diff_s = Math.floor(_tm_diff_ms / 1000);
+
+ //NEWS정보는 매 20분 마다 한번씩 업데이트
+ if (_tm_diff_s > 1200) {
+ g_tm_prev.news = _tm_cur;
+ _bNeed_Update.news = true;
+ }
+ }
+
+
+ // CHECK FLIGHT INFORMATION UPDATE
+ if (g_tm_prev.flight == null) {
+ g_tm_prev.flight = new Date();
+ _bNeed_Update.flight = true;
+ } else {
+ let _tm_diff_ms = _tm_cur.getTime() - g_tm_prev.flight.getTime();
+ let _tm_diff_s = Math.floor(_tm_diff_ms / 1000);
+
+ //FLIGHT정보는 매 60분 마다 한번씩 업데이트
+ if (_tm_diff_s > 3600) {
+ g_tm_prev.flight = _tm_cur;
+ _bNeed_Update.flight = true;
+ }
+ }
+
+ // CHECK WEATHER INFORMATION UPDATE
+ if (g_tm_prev.weather == null) {
+ g_tm_prev.weather = new Date();
+ _bNeed_Update.weather = true;
+ } else {
+ let _tm_diff_ms = _tm_cur.getTime() - g_tm_prev.weather.getTime();
+ let _tm_diff_s = Math.floor(_tm_diff_ms / 1000);
+
+ //NEWS정보는 매 2시간 마다 한번씩 업데이트
+ if (_tm_diff_s > 7200) {
+ g_tm_prev.weather = _tm_cur;
+ _bNeed_Update.weather = true;
+ }
+ }
+
+
+ // CHECK REPORT INFORMATION UPDATE
+ if (g_tm_prev.report == null) {
+ g_tm_prev.report = new Date();
+ _bNeed_Update.report = true;
+ } else {
+ let _tm_diff_ms = _tm_cur.getTime() - g_tm_prev.report.getTime();
+ let _tm_diff_s = Math.floor(_tm_diff_ms / 1000);
+
+ //REPORT는 매 5초 마다 한번씩 업데이트
+ if (_tm_diff_s > 5) {
+ g_tm_prev.report = _tm_cur;
+ _bNeed_Update.report = true;
+ }
+ }
+
+
+ // 후처리(실제 데이터 가져오고 부모에세 메시지로 안내)
+ if (_bNeed_Update.epg === true) {
+ let sz_api_url = __svcfxn_get_api_url("get_epg");
+ __svcfxn_CallCmsApi(sz_api_url, "GetEpg", null).then(_result => {
+ g_port.postMessage({ "event": "update_epg", "ret": "OK", "data": JSON.parse(_result.data) });
+ }).catch(_error => {
+ g_port.postMessage({ "event": "update_epg", "ret": "ERROR", "data": null });
+ });
+ }
+
+ if (_bNeed_Update.news === true) {
+ let sz_api_url = __svcfxn_get_api_url("get_news");
+ __svcfxn_CallCmsApi(sz_api_url, "GetNews", null).then(_result => {
+ g_port.postMessage({ "event": "update_news", "ret": "OK", "data": JSON.parse(_result.data) });
+ }).catch(_error => {
+ g_port.postMessage({ "event": "update_news", "ret": "ERROR", "data": null });
+ });
+ }
+
+ if (_bNeed_Update.flight == true) {
+ let sz_api_url = __svcfxn_get_api_url("get_flight");
+ __svcfxn_CallCmsApi(sz_api_url, "GetFlight", null).then(_result => {
+ g_port.postMessage({ "event": "update_flight", "ret": "OK", "data": JSON.parse(_result.data) });
+ }).catch(_error => {
+ g_port.postMessage({ "event": "update_flight", "ret": "ERROR", "data": null });
+ });
+ }
+
+ if (_bNeed_Update.weather == true) {
+ g_port.postMessage({ "event": "update_weather", "ret": "OK", "data": _bNeed_Update.weather });
+ }
+
+ if (_bNeed_Update.report == true) {
+ g_port.postMessage({ "event": "update_report", "ret": "OK", "data": _bNeed_Update.report });
+ }
+ resolve();
+ });
+};
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+onconnect = function(e) {
+ if (g_port != null) {
+ return;
+ }
+
+ g_port = e.ports[0];
+
+ g_port.addEventListener('message', function(e) {
+ let recvMsg = e.data;
+ if (recvMsg.cmd === "start_service") {
+ let _param = recvMsg.param;
+ g_config.token = _param.token;
+ g_config.dev_family = _param.dev_family;
+ g_config.dev_snum = _param.dev_snum;
+ g_config.svrinfo = _param.svrinfo;
+
+ //Periodic polling HotelTV API service
+ if (g_tmrHndl == null) {
+ g_tmrHndl = setTimeout(async function svcTask() {
+ await sworker_service();
+ g_tmrHndl = setTimeout(svcTask, 1000);
+ }, 0);
+ }
+ }
+ });
+
+ g_port.start(); // Required when using addEventListener. Otherwise called implicitly by onmessage setter.
+}
\ No newline at end of file
diff --git a/procentric/application/lib/hoteltv.ui_appfull.js b/procentric/application/lib/hoteltv.ui_appfull.js
new file mode 100755
index 0000000..961cf1a
--- /dev/null
+++ b/procentric/application/lib/hoteltv.ui_appfull.js
@@ -0,0 +1,4198 @@
+/**
+ * Copyright (c) 2020
+ *
+ * CENTIRM HotelTV UI-WELCOME module javascript.
+ *
+ * @summary short description for the file
+ * @author Joel
+ *
+ * Created at : 2020-11-26 02:21:56
+ * Last modified : 2020-11-26 15:31:40
+ */
+
+HotelTV.namespace('HotelTV.ui_appfull');
+HotelTV.ui_appfull = (function() {
+ //// 의존 관계 선언
+ var _hndl_mmSel = null;
+ var _hndl_mmBg = null;
+ var _hndl_smSel = null;
+ var _hndl_smBg = null;
+ var _hndl_mpSel = null;
+ var _hndl_mpBg = null;
+ var _hndl_ctzGenBg = null;
+ var _hndl_brochureBg = null;
+ var _hndl_widget_topTime = null;
+ var _hndl_tmrTvChnMngr = null;
+ var _hndl_tmrUgMngr = null;
+ var _hndl_tmrCtzThumbAni = null;
+ const _lastTm = {
+ 'tvchannel_changed': null,
+ 'keyevt': null,
+ };
+
+ //// 비공개 프로퍼티
+ /**
+ * HotelTV UI[AppFull] Wrapper Function::> Keydown event time recorder
+ * @param {dictionary} _evt event information
+ */
+ function __uifxn_AppFull_OnKeyDnEvtRec(_evt) {
+ let _tm_diff_ms = 0;
+
+ _lastTm.keyevt = new Date();
+ }
+
+
+
+
+ /**
+ * HotelTV UI Wrapper Function::> received event handling function
+ * @param {dictionary} _evt event information
+ */
+ function __uifxn_AppFull_OnMediaEvt(_evt) {
+ let _state = HotelTV.state;
+ console.log("media_event_received = " + _evt.eventType);
+ let _stateMedia = _evt.eventType;
+
+ if (_state.menu.stage == "ctzgen") {
+ switch (_stateMedia) {
+ case 'play_start':
+ _state.media.playing = true;
+ $('.main .ctzgen .bg .owl-carousel .owl-stage-outer .owl-stage .owl-item').removeClass('movieplay');
+ $('.main .ctzgen .bg .owl-carousel .owl-stage-outer .owl-stage .owl-item.active').addClass('movieplay');
+ $('.owl-theme .owl-nav.disabled+.owl-dots').fadeOut(500);
+ HotelTV.hcap.VideoWinSize(null);
+ break;
+ case 'play_end':
+ _state.media.playing = false;
+ HotelTV.hcap.MediaStop(
+ function() {
+ $('.main .ctzgen .bg .owl-carousel .owl-stage-outer .owl-stage .owl-item').removeClass('movieplay');
+ $('.owl-theme .owl-nav.disabled+.owl-dots').fadeIn(500);
+ },
+ function() {
+ $('.main .ctzgen .bg .owl-carousel .owl-stage-outer .owl-stage .owl-item').removeClass('movieplay');
+ $('.owl-theme .owl-nav.disabled+.owl-dots').fadeIn(500);
+ });
+ break;
+ case 'error_in_playing':
+ break;
+ case 'buffer_full':
+ break;
+ case 'file_not_found':
+ break;
+ case 'network_disconnected':
+ break;
+ case 'network_busy':
+ break;
+ case 'seek_done':
+ break;
+ }
+ }
+ }
+
+ /**
+ * HotelTV UI Wrapper Function::> received event handling function
+ * @param {dictionary} _evt event information
+ */
+ function __uifxn_AppFull_OnNetEvt(_evt) {
+ let _state = HotelTV.state;
+ console.log("network_event_received = " + _evt.eventType);
+ let _typeNetEvt = _evt.eventType;
+
+ switch (_typeNetEvt) {
+ case 'play_start':
+ break;
+ case 'play_end':
+ break;
+ case 'error_in_playing':
+ break;
+ case 'buffer_full':
+ break;
+ case 'file_not_found':
+ break;
+ case 'network_disconnected':
+ break;
+ case 'network_busy':
+ break;
+ case 'seek_done':
+ break;
+ }
+ }
+
+ /**
+ * HotelTV UI Wrapper Function::> received event handling function
+ * @param {dictionary} _evt event information
+ */
+ function __uifxn_AppFull_OnAppFocusEvt(_evt) {
+ let _state = HotelTV.state;
+ console.log("hcap_application_focus_changed = " + _evt.eventType);
+ let _typeAppFocusEvt = _evt.eventType;
+
+ if (_typeAppFocusEvt == "focused") {
+ HotelTV.hcap.SetSoftAp({
+ "enable": false,
+ });
+ }
+ }
+
+ /**
+ * HotelTV UI Wrapper Function::> received event handling function
+ * @param {dictionary} _evt event information
+ */
+ function __uifxn_AppFull_OnHdmiConChangeEvt(_evt) {
+ let _state = HotelTV.state;
+ // {Number} param.index - index of the HDMI which was connected or disconnected.
+ // {Boolean} param.connected - true if the HDMI is connected, else false.
+ console.log(
+ "Event 'hdmi_connection_changed' is received.\n" +
+ "HDMI-" + param.index + " : " + "connected = " + param.connected
+ );
+ }
+
+ /**
+ * HotelTV UI[AppFull] Wrapper Function::> show/hide special hotkey(red/yellow/green/blue/etc...) btn
+ * @param {boolean} e event
+ */
+ function __uifxn_AppFull_ShowMMHotKeyBtn(_show) {
+ let _state = HotelTV.state;
+ let _opening = HotelTV.opening;
+ let _brochure = _opening.brochures;
+
+ // Draw Amenity & Room Service
+ if (_opening.amenity) {
+ let _amenityCtz = _opening.amenity;
+ // TITLE
+ $(`.control .mm .hotkey_${_amenityCtz.button}`).text(_amenityCtz.title[_state.lang]);
+ // HOTKEY 버튼 Show/Hide
+ $(`.control .mm .hotkey_${_amenityCtz.button}`).css({ "background-image": "url(" + _amenityCtz.buttonImage.file.download + ")" });
+ $(`.control .mm .hotkey_${_amenityCtz.button}`).css({ "top": _amenityCtz.positionY + "%" });
+ $(`.control .mm .hotkey_${_amenityCtz.button}`).css({ "left": _amenityCtz.positionX + "%" });
+ if (_show == true) {
+ if ($(`.control .mm .hotkey_${_amenityCtz.button}`).css("display") == "none") {
+ $(`.control .mm .hotkey_${_amenityCtz.button}`).fadeIn(300);
+ }
+ } else {
+ if ($(`.control .mm .hotkey_${_amenityCtz.button}`).css("display") != "none") {
+ $(`.control .mm .hotkey_${_amenityCtz.button}`).fadeOut(300);
+ }
+ }
+ }
+
+ if (_opening.roomService) {
+ let _roomserviceCtz = _opening.roomService;
+ // TITLE
+ $(`.control .mm .hotkey_${_roomserviceCtz.button}`).text(_roomserviceCtz.title[_state.lang]);
+ // HOTKEY 버튼 Show/Hide
+ $(`.control .mm .hotkey_${_roomserviceCtz.button}`).css({ "background-image": "url(" + _roomserviceCtz.buttonImage.file.download + ")" });
+ $(`.control .mm .hotkey_${_roomserviceCtz.button}`).css({ "top": _roomserviceCtz.positionY + "%" });
+ $(`.control .mm .hotkey_${_roomserviceCtz.button}`).css({ "left": _roomserviceCtz.positionX + "%" });
+ if (_show == true) {
+ if ($(`.control .mm .hotkey_${_roomserviceCtz.button}`).css("display") == "none") {
+ $(`.control .mm .hotkey_${_roomserviceCtz.button}`).fadeIn(300);
+ }
+ } else {
+ if ($(`.control .mm .hotkey_${_roomserviceCtz.button}`).css("display") != "none") {
+ $(`.control .mm .hotkey_${_roomserviceCtz.button}`).fadeOut(300);
+ }
+ }
+ }
+
+ // Draw Brochure contents
+ for (let _idx = 1; _idx <= _brochure.length; _idx++) {
+ let _brcCtz = _brochure[_idx];
+ // TITLE
+ $(`.control .mm .hotkey_${_brcCtz.button}`).text(_brcCtz.title[_state.lang]);
+ // HOTKEY 버튼 Show/Hide
+ $(`.control .mm .hotkey_${_brcCtz.button}`).css({ "background-image": "url(" + _brcCtz.buttonImage.file.download + ")" });
+ $(`.control .mm .hotkey_${_brcCtz.button}`).css({ "top": _brcCtz.positionY + "%" });
+ $(`.control .mm .hotkey_${_brcCtz.button}`).css({ "left": _brcCtz.positionX + "%" });
+ if (_show == true) {
+ if ($(`.control .mm .hotkey_${_brcCtz.button}`).css("display") == "none") {
+ $(`.control .mm .hotkey_${_brcCtz.button}`).fadeIn(300);
+ }
+ } else {
+ if ($(`.control .mm .hotkey_${_brcCtz.button}`).css("display") != "none") {
+ $(`.control .mm .hotkey_${_brcCtz.button}`).fadeOut(300);
+ }
+ }
+ }
+ }
+
+ /**
+ * HotelTV UI[AppFull] Wrapper Function::> build Brochure and In-room dining
+ * @param {boolean} e event
+ */
+ function __uifxn_AppFull_BuildBrochure() {
+ let _state = HotelTV.state;
+ let _brochure = HotelTV.opening.brochures;
+
+ for (let _idx = 1; _idx <= _brochure.length; _idx++) {
+ let _brcCtz = _brochure[_idx];
+ // BROCHURE 이미지 노드를 동적으로 구성
+ let _div_popup_mm_red_bglist = document.querySelector(`#lst_hotkey_mm_${_brcCtz.button}`);
+ for (let _page_idx = 1; _page_idx <= _brcCtz.page[_state.lang].length; _page_idx++) {
+ let _div_popup_mm_red_item = document.createElement('div');
+ let _sz_styleOpt = null;
+ _div_popup_mm_red_item.className = 'item';
+ _div_popup_mm_red_item.setAttribute(`popup_hotkey_mm_${_brcCtz.button}`, _page_idx);
+ _sz_styleOpt = "background-image: url(" + _brcCtz.page[_state.lang][_page_idx].download + "); ";
+ _sz_styleOpt += "background-repeat: no-repeat; background-position: center center; background-size: 100% 100%; ";
+ _div_popup_mm_red_item.setAttribute("style", _sz_styleOpt);
+
+ _div_popup_mm_red_bglist.appendChild(_div_popup_mm_red_item);
+ }
+ _hndl_brochureBg = $(`#lst_hotkey_mm_${_brcCtz.button}`);
+ _hndl_brochureBg.owlCarousel({
+ center: false,
+ items: 1, //Number of Items on Screen what you want
+ nav: true,
+ loop: false,
+ margin: 0,
+ smartSpeed: 1000,
+ lazyLoad: true,
+ mouseDrag: false,
+ touchDrag: false,
+ pullDrag: false,
+ freeDrag: false,
+ startPosition: 0,
+ });
+
+ // HOTKEY정보를 state에 기록
+ if (!(_brcCtz.button in _state.hotkey.mm)) {
+ _state.hotkey.mm[_brcCtz.button] = { 'type': "brochure" };
+ }
+ }
+ }
+
+ /**
+ * HotelTV UI[AppFull] Wrapper Function::> update amenity item
+ * @param {boolean} e event
+ */
+ async function __uifxn_AppFull_DrawAmenityItem() {
+ let _state = HotelTV.state;
+ let _amenity = HotelTV.opening.amenity;
+ let _carts = null;
+ let _elAmItemsRoot = $(`.popup .amenity>.items`);
+
+ const __fxn_fmexist = function(_object, _itemID) {
+ for (__j = 1; __j <= _object.length; __j++) {
+ if (_object[__j].itemId == _itemID) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ const __fxn_fmvalue = function(_object, _key, _itemID) {
+ for (__j = 1; __j <= _object.length; __j++) {
+ if (_object[__j].itemId == _itemID) {
+ return _object[__j][_key];
+ }
+ }
+ }
+
+ try {
+ HotelTV.carts.amenity = _carts = await HotelTV.api.GetAmenityCarts();
+ for (let _idx = 1; _idx <= _amenity.children.length; _idx++) {
+ let _amItem = _amenity.children[_idx];
+ let _elAmItemTblRecRoot = _elAmItemsRoot.children('table').children(`tr#${_amItem.id}`).children('div.products');
+ if (_carts.items.length && __fxn_fmexist(_carts.items, _amItem.id) == true) {
+ // Free count value
+ _elAmItemTblRecRoot.children('div#details').children(`div#freecnt_val`).text(__fxn_fmvalue(_carts.items, "freeCount", _amItem.id));
+ // Price value
+ _elAmItemTblRecRoot.children('div#details').children(`div#price_val`).text(__fxn_fmvalue(_carts.items, "price", _amItem.id)[_state.lang] + _amenity.currency[_state.lang]);
+ // Order Count
+ _elAmItemTblRecRoot.children(`div#quantity_val`).text(__fxn_fmvalue(_carts.items, "quantity", _amItem.id));
+ }
+ }
+ } catch (_error) {
+ console.log(`Fail to call API::> ${_error}`);
+ }
+ }
+
+ /**
+ * HotelTV UI[AppFull] Wrapper Function::> build amenity
+ * @param {boolean} e event
+ */
+ async function __uifxn_AppFull_BuildAmenityOrderDetails() {
+ let _state = HotelTV.state;
+ let _trTbl = HotelTV.translation;
+ let _opening = HotelTV.opening;
+ let _elAmODRoot = $(`.popup .amenity>.order-details`);
+ let _amenity = null;
+
+ const __fxn_fmvalue = function(_object, _key, _itemID) {
+ for (__j = 1; __j <= _object.length; __j++) {
+ if (_object[__j].id == _itemID) {
+ return _object[__j][_key];
+ }
+ }
+ }
+
+ if (!_opening.amenity) {
+ return;
+ }
+ _amenity = _opening.amenity;
+
+ try {
+ HotelTV.orders.amenity = _order = await HotelTV.api.GetAmenityOrders(null);
+ } catch (_error) {
+ console.log(`Fail to call API::> ${_error}`);
+ return;
+ }
+
+
+ _elAmODRoot.children('.title').text(_trTbl.ui.amenity.title.carts[_state.lang]);
+ _elAmODRoot.children('.usage').text(_trTbl.ui.amenity.usage.details[_state.lang]);
+
+ //Draw Amenity Order Items
+ try {
+ let _elAmDOdItemsRoot = _elAmODRoot.children(`.items`);
+
+ // Delete elements under amenity item table
+ if (_elAmDOdItemsRoot.children('table').children('tr').length) {
+ _elAmDOdItemsRoot.children('table').children('tr').remove();
+ }
+
+ let _eltbl_am_items = _elAmDOdItemsRoot.children('table#item_list');
+ for (let _odix = 1; _odix <= _order.orders.length; _odix++) {
+ let _amOrds = _order.orders[_odix];
+ for (let _idx = 1; _idx <= _amOrds.items.length; _idx++) {
+ let _amOrdItem = _amOrds.items[_idx];
+ var _eltr_item = document.createElement('tr');
+ _eltr_item.setAttribute("id", `${_odix}-${_idx}`);
+ _eltr_item.setAttribute("ctz_idx", (_odix - 1) * _order.orders.length + _idx);
+ //어메니티 아이탬 화면 드로잉
+ var _eldiv_item_ctz = document.createElement('div');
+ _eldiv_item_ctz.setAttribute("class", "products");
+
+ // Append Sub elements::title
+ let _elDiv_odNum = document.createElement('div');
+ _elDiv_odNum.setAttribute("id", "order_num");
+ _elDiv_odNum.textContent = `${_trTbl.ui.amenity.title.ordernum[_state.lang]} ${_amOrds.id}`;
+ _eldiv_item_ctz.appendChild(_elDiv_odNum);
+
+ // Append Sub elements::thumbnail iamge
+ let _elDiv_thumb = document.createElement('div');
+ _elDiv_thumb.setAttribute("id", "thumb");
+ let _sz_styleOpt = "background-image: url(" + __fxn_fmvalue(_amenity.children, "thumbnail", _amOrdItem.itemId).file.download + "); ";
+ _sz_styleOpt += "background-repeat: no-repeat; background-position: center center; background-size: contain ";
+ _elDiv_thumb.setAttribute("style", _sz_styleOpt);
+ _eldiv_item_ctz.appendChild(_elDiv_thumb);
+
+ // Append Sub elements::quantity and amount summary
+ let _elDiv_summary = document.createElement('div');
+ _elDiv_summary.setAttribute("id", "summary");
+
+ // Append Sub elements::free count Order quantity_title
+ let _elDiv_quantityTitle = document.createElement('div');
+ _elDiv_quantityTitle.setAttribute("id", "quantity_title");
+ _elDiv_quantityTitle.textContent = _trTbl.ui.amenity.title.quantity[_state.lang];
+ _elDiv_summary.appendChild(_elDiv_quantityTitle);
+
+ // Append Sub elements::free count Order amount_title
+ let _elDiv_amountTitle = document.createElement('div');
+ _elDiv_amountTitle.setAttribute("id", "amount_title");
+ _elDiv_amountTitle.textContent = _trTbl.ui.amenity.title.amount[_state.lang];
+ _elDiv_summary.appendChild(_elDiv_amountTitle);
+
+ // Append Sub elements::free count Order quantity_val
+ let _elDiv_quantity = document.createElement('div');
+ _elDiv_quantity.setAttribute("id", "quantity_val");
+ _elDiv_quantity.textContent = _amOrdItem.quantity;
+ _elDiv_summary.appendChild(_elDiv_quantity);
+
+ // Append Sub elements::free count Order amount_val
+ let _elDiv_amount = document.createElement('div');
+ _elDiv_amount.setAttribute("id", "amount_val");
+ _elDiv_amount.textContent = `${_order.currency[_state.lang]}${_amOrdItem.amount[_state.lang]}`;
+ _elDiv_summary.appendChild(_elDiv_amount);
+
+ _eldiv_item_ctz.appendChild(_elDiv_summary);
+ _eltr_item.appendChild(_eldiv_item_ctz);
+ _eltbl_am_items.append(_eltr_item);
+ }
+ }
+ // 첫번째 테이블 아애템에 active 클래스 추가 (플래그용으로 사용)
+ _elAmDOdItemsRoot.children('table').children('tr').first().addClass('active');
+ } catch (_error) {
+ console.log(_error.message);
+ }
+
+ _elAmODRoot.children('.total_amount').children('.title').text(_trTbl.ui.amenity.title.Sum[_state.lang]);
+ _elAmODRoot.children('.total_amount').children('.value').text(`${_order.currency[_state.lang]}${_order.amount[_state.lang]}`);
+
+ // last_OrderTbl_idx 초기화
+ if (!(_amenity.button in _state.hotkey.mm)) {
+ _state.hotkey.mm[_amenity.button].last_OrderTbl_idx = 0;
+ }
+ }
+
+ /**
+ * HotelTV UI[AppFull] Wrapper Function::> build amenity
+ * @param {boolean} e event
+ */
+ function __uifxn_AppFull_BuildAmenity() {
+ let _state = HotelTV.state;
+ let _trTbl = HotelTV.translation;
+ let _opening = HotelTV.opening;
+ let _order = HotelTV.orders.amenity;
+ let _amenity = null;
+ let _elAmRoot = $(`.popup .amenity`);
+ let _elAmBtnRoot = $(`.popup .amenity>.buttons`);
+
+ if (!_opening.amenity) {
+ return;
+ }
+ _amenity = _opening.amenity;
+
+ _elAmRoot.children('.title').text(_amenity.title[_state.lang]);
+ _elAmRoot.children('.usage').text(_trTbl.ui.amenity.usage.order[_state.lang]);
+
+ //Draw Amenity Cart Items
+ let _elAmItemsRoot = $(`.popup .amenity>.items`);
+ try {
+ // Delete elements under amenity item table
+ if (_elAmItemsRoot.children('table').children('tr').length) {
+ _elAmItemsRoot.children('table').children('tr').remove();
+ }
+
+ let _eltbl_am_items = _elAmItemsRoot.children('.table#item_list');;
+ for (let _idx = 1; _idx <= _amenity.children.length; _idx++) {
+ let _amItem = _amenity.children[_idx];
+
+ var _eltr_item = document.createElement('tr');
+ _eltr_item.setAttribute("id", _amenity.children[_idx].id);
+ _eltr_item.setAttribute("ctz_idx", _idx);
+ //어메니티 아이탬 화면 드로잉
+ var _eldiv_item_ctz = document.createElement('div');
+ _eldiv_item_ctz.setAttribute("class", "products");
+
+ // Append Sub elements::title
+ let _elDiv_title = document.createElement('div');
+ _elDiv_title.setAttribute("id", "item_title");
+ _elDiv_title.textContent = _amItem.title[_state.lang];
+ _eldiv_item_ctz.appendChild(_elDiv_title);
+
+ // Append Sub elements::thumbnail iamge
+ let _elDiv_thumb = document.createElement('div');
+ _elDiv_thumb.setAttribute("id", "thumb");
+ let _sz_styleOpt = "background-image: url(" + _amItem.thumbnail.file.download + "); ";
+ _sz_styleOpt += "background-repeat: no-repeat; background-position: center center; background-size: contain ";
+ _elDiv_thumb.setAttribute("style", _sz_styleOpt);
+ _eldiv_item_ctz.appendChild(_elDiv_thumb);
+
+ // Append Sub elements::free count Title & Value
+ let _elDiv_details = document.createElement('div');
+ _elDiv_details.setAttribute("id", "details");
+ let _elDiv_freecntTitle = document.createElement('div');
+ _elDiv_freecntTitle.setAttribute("id", "freecnt_title");
+ _elDiv_freecntTitle.textContent = _trTbl.ui.amenity.title.freecnt[_state.lang];
+ _elDiv_details.appendChild(_elDiv_freecntTitle);
+
+ let _elDiv_freecntValue = document.createElement('div');
+ _elDiv_freecntValue.setAttribute("id", "freecnt_val");
+ _elDiv_freecntValue.textContent = "";
+ _elDiv_details.appendChild(_elDiv_freecntValue);
+
+ // Append Sub elements::price Title & Value
+ let _elDiv_priceTitle = document.createElement('div');
+ _elDiv_priceTitle.setAttribute("id", "price_title");
+ _elDiv_priceTitle.textContent = _trTbl.ui.amenity.title.price[_state.lang];
+ _elDiv_details.appendChild(_elDiv_priceTitle);
+
+ let _elDiv_priceValue = document.createElement('div');
+ _elDiv_priceValue.setAttribute("id", "price_val");
+ _elDiv_priceValue.textContent = "";
+ _elDiv_details.appendChild(_elDiv_priceValue);
+ _eldiv_item_ctz.appendChild(_elDiv_details);
+
+
+
+ // Append Sub elements::free count Order quantity_val
+ let _elDiv_quantity = document.createElement('div');
+ _elDiv_quantity.setAttribute("id", "quantity_val");
+ _elDiv_quantity.textContent = "";
+ _eldiv_item_ctz.appendChild(_elDiv_quantity);
+
+
+ _eltr_item.appendChild(_eldiv_item_ctz);
+ _eltbl_am_items.append(_eltr_item);
+ }
+ // 첫번째 테이블 아애템에 active 클래스 추가 (플래그용으로 사용)
+ _elAmItemsRoot.children('.table').children('tr').first().addClass('active');
+ } catch (_error) {
+ console.log(_error.message);
+ }
+
+ //Fill up amenity important information such as free count and price, etc...
+ __uifxn_AppFull_DrawAmenityItem();
+
+ _elAmBtnRoot.children('.order').text(_trTbl.ui.amenity.title.order[_state.lang]);
+ _elAmBtnRoot.children('.cancel').text(_trTbl.ui.amenity.title.cancel[_state.lang]);
+ _elAmBtnRoot.children('.details').text(_trTbl.ui.amenity.title.carts[_state.lang]);
+
+ // HOTKEY정보를 state에 기록
+ if (!(_amenity.button in _state.hotkey.mm)) {
+ _state.hotkey.mm[_amenity.button] = {
+ 'type': "amenity",
+ "status": {
+ "focus": "table",
+ "last_CartTbl_idx": 0,
+ "last_CartBtn_idx": null,
+ "last_OrderTbl_idx": 0,
+ }
+ };
+ }
+ }
+
+ /**
+ * HotelTV UI[AppFull] Wrapper Function::> amenity handling function
+ * @param {boolean} e event
+ */
+ async function __uifxn_AppFull_HandleAmenity(_evt, _isFlushCart, _isDoOrder) {
+ let _state = HotelTV.state;
+ let _trTbl = HotelTV.translation;
+ let _opening = HotelTV.opening;
+ let _amenity = null;
+ let _carts = HotelTV.carts.amenity;
+ let _scrollTopVal = 0;
+ const _checkEmptyOrder = function(_object) {
+ for (__j = 1; __j <= _object.length; __j++) {
+ if (_object[__j].id) {
+ return false;
+ }
+ }
+ return true;
+ }
+
+ if (!_opening.amenity) {
+ return;
+ }
+ _amenity = _opening.amenity;
+
+ if (_evt == "up") {
+ if (_state.hotkey.mm[_amenity.button].status.focus == "table") {
+ let activeTableRow = $('.popup .amenity>.items table tr.active').prev(".table tr");
+ if (activeTableRow.length) {
+ $('.popup .amenity>.items table tr.active').removeClass("active");
+ activeTableRow.addClass('active');
+ _state.hotkey.mm[_amenity.button].status.last_CartTbl_idx = activeTableRow.prop('rowIndex');
+
+ _scrollTopVal = activeTableRow.prop('scrollHeight') * _state.hotkey.mm[_amenity.button].status.last_CartTbl_idx;
+ $('.popup .amenity>.items').animate({ scrollTop: _scrollTopVal }, 500);
+ }
+ } else if (_state.hotkey.mm[_amenity.button].status.focus == "button") {
+ if (_state.hotkey.mm[_amenity.button].status.last_CartBtn_idx == "details") {
+ _state.hotkey.mm[_amenity.button].status.last_CartBtn_idx = "cancel";
+ $('.popup .amenity>.buttons div').removeClass("active");
+ $('.popup .amenity>.buttons div.cancel').addClass("active");
+ } else if (_state.hotkey.mm[_amenity.button].status.last_CartBtn_idx == "cancel") {
+ if (_checkEmptyOrder(_carts.items) == false) {
+ _state.hotkey.mm[_amenity.button].status.last_CartBtn_idx = "order";
+ $('.popup .amenity>.buttons div').removeClass("active");
+ $('.popup .amenity>.buttons div.order').addClass("active");
+ } else {
+ _state.hotkey.mm[_amenity.button].status.last_CartBtn_idx = null;
+ _state.hotkey.mm[_amenity.button].status.focus = "table";
+ $('.popup .amenity>.buttons div').removeClass("active");
+ $('.popup .amenity>.items table tr').eq(_state.hotkey.mm[_amenity.button].status.last_CartTbl_idx).addClass('active');
+ }
+ } else {
+ _state.hotkey.mm[_amenity.button].status.last_CartBtn_idx = null;
+ _state.hotkey.mm[_amenity.button].status.focus = "table";
+ $('.popup .amenity>.buttons div').removeClass("active");
+ $('.popup .amenity>.items table tr').eq(_state.hotkey.mm[_amenity.button].status.last_CartTbl_idx).addClass('active');
+ }
+ } else if (_state.hotkey.mm[_amenity.button].status.focus == "order_details") {
+ let activeTableRow = $('.popup .amenity>.order-details>.items table tr.active').prev(".table tr");
+ if (activeTableRow.length) {
+ $('.popup .amenity>.order-details>.items table tr.active').removeClass("active");
+ activeTableRow.addClass('active');
+ _state.hotkey.mm[_amenity.button].status.last_OrderTbl_idx = activeTableRow.prop('rowIndex');
+
+ _scrollTopVal = activeTableRow.prop('scrollHeight') * _state.hotkey.mm[_amenity.button].status.last_OrderTbl_idx;
+ $('.popup .amenity>.order-details>.items').animate({ scrollTop: _scrollTopVal }, 500);
+ }
+ }
+ console.log(`STATUS::> ${JSON.stringify(_state.hotkey.mm[_amenity.button].status)}`);
+ } else if (_evt == "down") {
+ if (_state.hotkey.mm[_amenity.button].status.focus == "table") {
+ let activeTableRow = $('.popup .amenity>.items table tr.active').next(".table tr");
+ if (activeTableRow.length) {
+ $('.popup .amenity>.items table tr.active').removeClass("active");
+ activeTableRow.addClass('active');
+ _state.hotkey.mm[_amenity.button].status.last_CartTbl_idx = activeTableRow.prop('rowIndex');
+
+ _scrollTopVal = activeTableRow.prop('scrollHeight') * _state.hotkey.mm[_amenity.button].status.last_CartTbl_idx;
+ $('.popup .amenity>.items').animate({ scrollTop: _scrollTopVal }, 500);
+ } else {
+ _state.hotkey.mm[_amenity.button].status.focus = "button";
+ if (!_state.hotkey.mm[_amenity.button].status.last_CartBtn_idx) {
+ $('.popup .amenity>.items table tr.active').removeClass("active");
+
+ $('.popup .amenity>.buttons div').removeClass("active");
+ if (_checkEmptyOrder(_carts.items) == false) {
+ _state.hotkey.mm[_amenity.button].status.last_CartBtn_idx = "order";
+ $('.popup .amenity>.buttons div.order').addClass("active");
+ } else {
+ _state.hotkey.mm[_amenity.button].status.last_CartBtn_idx = "cancel";
+ $('.popup .amenity>.buttons div.cancel').addClass("active");
+ }
+
+ }
+ }
+ } else if (_state.hotkey.mm[_amenity.button].status.focus == "button") {
+ if (_state.hotkey.mm[_amenity.button].status.last_CartBtn_idx == "order") {
+ _state.hotkey.mm[_amenity.button].status.last_CartBtn_idx = "cancel";
+ $('.popup .amenity>.buttons div').removeClass("active");
+ $('.popup .amenity>.buttons div.cancel').addClass("active");
+ } else if (_state.hotkey.mm[_amenity.button].status.last_CartBtn_idx == "cancel") {
+ _state.hotkey.mm[_amenity.button].status.last_CartBtn_idx = "details";
+ $('.popup .amenity>.buttons div').removeClass("active");
+ $('.popup .amenity>.buttons div.details').addClass("active");
+ }
+ } else if (_state.hotkey.mm[_amenity.button].status.focus == "order_details") {
+ let activeTableRow = $('.popup .amenity>.order-details>.items table tr.active').next(".table tr");
+ if (activeTableRow.length) {
+ $('.popup .amenity>.order-details>.items table tr.active').removeClass("active");
+ activeTableRow.addClass('active');
+ _state.hotkey.mm[_amenity.button].status.last_OrderTbl_idx = activeTableRow.prop('rowIndex');
+
+ _scrollTopVal = activeTableRow.prop('scrollHeight') * _state.hotkey.mm[_amenity.button].status.last_OrderTbl_idx;
+ $('.popup .amenity>.order-details>.items').animate({ scrollTop: _scrollTopVal }, 200);
+ }
+ }
+ console.log(`STATUS::> ${JSON.stringify(_state.hotkey.mm[_amenity.button].status)}`);
+ } else if (_evt == "enter") {
+ _state.hotkey.mm[_amenity.button].status.focus = "order_details";
+ } else if (_evt == "reset") {
+ _state.hotkey.mm[_amenity.button].status = {
+ "focus": "table",
+ "last_CartTbl_idx": 0,
+ "last_CartBtn_idx": null,
+ "last_OrderTbl_idx": 0,
+ };
+ $('.popup .amenity>.buttons div').removeClass("active");
+ $('.popup .amenity>.items table tr').removeClass("active");
+ $('.popup .amenity>.items table tr:first').addClass('active');
+ $('.popup .amenity>.order-details>.items table tr').removeClass("active");
+ $('.popup .amenity>.order-details>.items table tr:first').addClass('active');
+
+ // Flush CART
+ if (_isFlushCart == true && HotelTV.carts.amenity.items) {
+ let _cartsItems = HotelTV.carts.amenity.items;
+ for (_k = 1; _k <= _cartsItems.length; _k++) {
+ if (_cartsItems[_k].id) {
+ try {
+ let _result = await HotelTV.api.DeleteAmenityCarts(_cartsItems[_k].id);
+ if (_result) {
+ console.log(`Success to flush CARTID::> ${_cartsItems[_k].id}`);
+ } else {
+ console.log(`Fail to flush CARTID::> ${_cartsItems[_k].id}`);
+ }
+ } catch (_error) {
+ console.log(`Fail to call API::> ${_error}`);
+ }
+ }
+ }
+ __uifxn_AppFull_DrawAmenityItem();
+ }
+
+ // Order
+ if (_isDoOrder == true && HotelTV.carts.amenity.items) {
+ try {
+ let _result = await HotelTV.api.PutAmenityOrders();
+ if (_result) {
+ console.log(`Success to order CARTID::>`);
+ __uifxn_AppFull_DrawAmenityItem();
+ } else {
+ console.log(`Fail to order CARTID::>`);
+ }
+ } catch (_error) {
+ console.log(`Fail to call API::> ${_error}`);
+ }
+ }
+ } else if (_evt == "add") {
+ if (_state.hotkey.mm[_amenity.button].status.focus == "table") {
+ let activedTableRow = $('.popup .amenity>.items table tr.active');
+ let _sel_itemID = activedTableRow.attr('id');
+ try {
+ let _result = await HotelTV.api.PutAmenityCarts(_sel_itemID, 1);
+ if (_result) {
+ __uifxn_AppFull_DrawAmenityItem();
+ }
+ } catch (_error) {
+ console.log(`Fail to call API::> ${_error}`);
+ }
+ }
+ } else if (_evt == "del") {
+ if (_state.hotkey.mm[_amenity.button].status.focus == "table") {
+ let activedTableRow = $('.popup .amenity>.items table tr.active');
+ let _sel_itemID = activedTableRow.attr('id');
+ try {
+ let _result = await HotelTV.api.PutAmenityCarts(_sel_itemID, -1);
+ if (_result) {
+ __uifxn_AppFull_DrawAmenityItem();
+ }
+ } catch (_error) {
+ console.log(`Fail to call API::> ${_error}`);
+ }
+ }
+ }
+ }
+
+
+ /**
+ * HotelTV UI[AppFull] Wrapper Function::> update room service item
+ * @param {boolean} e event
+ */
+ async function __uifxn_AppFull_DrawRoomserviceItem() {
+ let _state = HotelTV.state;
+ let _roomservice = HotelTV.opening.roomService;
+ let _carts = null;
+ const __fxn_fmexist = function(_object, _itemID) {
+ for (__j = 1; __j <= _object.length; __j++) {
+ if (_object[__j].itemId == _itemID) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ const __fxn_fmvalue = function(_object, _key, _itemID) {
+ for (__j = 1; __j <= _object.length; __j++) {
+ if (_object[__j].itemId == _itemID) {
+ return _object[__j][_key];
+ }
+ }
+ }
+
+ try {
+ let _elRsMnRoot = $(`.popup .roomservice .menu`);
+
+ HotelTV.carts.roomservice = _carts = await HotelTV.api.GetRoomserviceCarts();
+ for (let _idx = 1; _idx <= _roomservice.children.length; _idx++) {
+ let _rsItem = _roomservice.children[_idx];
+ let _elRsItemTblRecRoot = _elRsMnRoot.children('div.items').children('table').children(`tr#${_rsItem.id}`).children('div.products');
+ if (_carts.items.length && __fxn_fmexist(_carts.items, _rsItem.id) == true) {
+ // amount value
+ _elRsItemTblRecRoot.children('div#details').children('#price').text(__fxn_fmvalue(_carts.items, "amount", _rsItem.id)[_state.lang] + _roomservice.currency[_state.lang]);
+ // Order Count
+ _elRsItemTblRecRoot.children('div#details').children('#quantity').children(`#value`).text(__fxn_fmvalue(_carts.items, "quantity", _rsItem.id));
+ }
+ }
+ } catch (_error) {
+ console.log(_error.message);
+ }
+ }
+
+ /**
+ * HotelTV UI[AppFull] Wrapper Function::> build roomservice details
+ * @param {boolean} e event
+ */
+ async function __uifxn_AppFull_BuildRoomserviceOrderDetails() {
+ let _state = HotelTV.state;
+ let _trTbl = HotelTV.translation;
+ let _opening = HotelTV.opening;
+ let _roomservice = null;
+ let _elRsODRoot = $(`.popup .roomservice .menu>.order-details`);
+
+ const __fxn_fmvalue = function(_object, _key, _itemID) {
+ for (__j = 1; __j <= _object.length; __j++) {
+ if (_object[__j].id == _itemID) {
+ return _object[__j][_key];
+ }
+ }
+ }
+
+ if (!_opening.roomService) {
+ return;
+ }
+ _roomservice = _opening.roomService;
+
+ try {
+ HotelTV.orders.roomservice = _order = await HotelTV.api.GetRoomserviceOrders(null);
+ } catch (_error) {
+ console.log(`Fail to call API::> ${_error}`);
+ return;
+ }
+
+
+ _elRsODRoot.children(`.title`).text(_trTbl.ui.roomservice.title.carts[_state.lang]);
+ _elRsODRoot.children(`.usage`).text(_trTbl.ui.roomservice.usage.details[_state.lang]);
+
+ //Draw Room service Order Items
+ try {
+ // Delete elements under room service item table
+ let _elRsRDOdItemsRoot = _elRsODRoot.children(`.items`);
+
+ if (_elRsRDOdItemsRoot.children('table').children('tr').length) {
+ _elRsRDOdItemsRoot.children('table').children('tr').remove();
+ }
+
+ let _eltbl_am_items = _elRsODRoot.children('.items').children('.table#item_list');
+ for (let _odix = 1; _odix <= _order.orders.length; _odix++) {
+ let _rsOrds = _order.orders[_odix];
+ for (let _idx = 1; _idx <= _rsOrds.items.length; _idx++) {
+ let _rsOrdItem = _rsOrds.items[_idx];
+ var _eltr_item = document.createElement('tr');
+ _eltr_item.setAttribute("id", `${_odix}-${_idx}`);
+ _eltr_item.setAttribute("ctz_idx", (_odix - 1) * _order.orders.length + _idx);
+ //어메니티 아이탬 화면 드로잉
+ var _eldiv_item_ctz = document.createElement('div');
+ _eldiv_item_ctz.setAttribute("class", "products");
+
+ // Append Sub elements::title
+ let _elDiv_odNum = document.createElement('div');
+ _elDiv_odNum.setAttribute("id", "order_num");
+ _elDiv_odNum.textContent = `${_trTbl.ui.roomservice.title.ordernum[_state.lang]} ${_rsOrds.id}`;
+ _eldiv_item_ctz.appendChild(_elDiv_odNum);
+
+ // Append Sub elements::thumbnail iamge
+ let _elDiv_thumb = document.createElement('div');
+ _elDiv_thumb.setAttribute("id", "thumb");
+ // let _sz_styleOpt = "background-image: url(" + __fxn_fmvalue(_roomservice.children, "thumbnail", _rsOrdItem.itemId).file.download + "); ";
+ // _sz_styleOpt += "background-repeat: no-repeat; background-position: center center; background-size: contain ";
+ // _elDiv_thumb.setAttribute("style", _sz_styleOpt);
+ _eldiv_item_ctz.appendChild(_elDiv_thumb);
+
+ // Append Sub elements::quantity and amount summary
+ let _elDiv_summary = document.createElement('div');
+ _elDiv_summary.setAttribute("id", "summary");
+
+ // Append Sub elements::free count Order quantity_title
+ let _elDiv_quantityTitle = document.createElement('div');
+ _elDiv_quantityTitle.setAttribute("id", "quantity_title");
+ _elDiv_quantityTitle.textContent = _trTbl.ui.roomservice.title.quantity[_state.lang];
+ _elDiv_summary.appendChild(_elDiv_quantityTitle);
+
+ // Append Sub elements::free count Order amount_title
+ let _elDiv_amountTitle = document.createElement('div');
+ _elDiv_amountTitle.setAttribute("id", "amount_title");
+ _elDiv_amountTitle.textContent = _trTbl.ui.roomservice.title.amount[_state.lang];
+ _elDiv_summary.appendChild(_elDiv_amountTitle);
+
+ // Append Sub elements::free count Order quantity_val
+ let _elDiv_quantity = document.createElement('div');
+ _elDiv_quantity.setAttribute("id", "quantity_val");
+ _elDiv_quantity.textContent = _rsOrdItem.quantity;
+ _elDiv_summary.appendChild(_elDiv_quantity);
+
+ // Append Sub elements::free count Order amount_val
+ let _elDiv_amount = document.createElement('div');
+ _elDiv_amount.setAttribute("id", "amount_val");
+ _elDiv_amount.textContent = `${_order.currency[_state.lang]}${_rsOrdItem.amount[_state.lang]}`;
+ _elDiv_summary.appendChild(_elDiv_amount);
+
+ _eldiv_item_ctz.appendChild(_elDiv_summary);
+ _eltr_item.appendChild(_eldiv_item_ctz);
+ _eltbl_am_items.append(_eltr_item);
+ }
+ }
+ // 첫번째 테이블 아애템에 active 클래스 추가 (플래그용으로 사용)
+ _elRsRDOdItemsRoot.children('table').children('tr').first().addClass('active');
+ //$('.popup .roomservice .menu>.order-details>.items table tr:first').addClass('active');
+ } catch (_error) {
+ console.log(_error.message);
+ }
+ _elRsODRoot.children('.total_amount').children('.title').text(_trTbl.ui.roomservice.title.Sum[_state.lang]);
+ _elRsODRoot.children('.total_amount').children('.value').text(`${_order.currency[_state.lang]}${_order.amount[_state.lang]}`);
+
+ // last_OrderTbl_idx 초기화
+ if (!(_roomservice.button in _state.hotkey.mm)) {
+ _state.hotkey.mm[_roomservice.button].last_OrderTbl_idx = 0;
+ }
+ }
+
+ /**
+ * HotelTV UI[AppFull] Wrapper Function::> build room service
+ * @param {boolean} e event
+ */
+ function __uifxn_AppFull_BuildRoomService() {
+ let _state = HotelTV.state;
+ let _trTbl = HotelTV.translation;
+ let _opening = HotelTV.opening;
+ let _order = HotelTV.orders.roomService;
+ let _roomservice = null;
+ let _elRsMnRoot = $(`.popup .roomservice .menu`);
+ let _elRsMnBtn = $(`.popup .roomservice .menu .buttons`);
+ let _elRsMnDesc = $(`.popup .roomservice .description`);
+
+ const __fxn_fmvalue = function(_object, _key, _itemID) {
+ for (__j = 1; __j <= _object.length; __j++) {
+ if (_object[__j].id == _itemID) {
+ return _object[__j][_key];
+ }
+ }
+ }
+
+ if (!_opening.roomService) {
+ return;
+ }
+ _roomservice = _opening.roomService;
+
+ _elRsMnRoot.children('.title').text(_roomservice.title[_state.lang]);
+ _elRsMnRoot.children('.usage').text(_trTbl.ui.roomservice.usage.order[_state.lang]);
+
+ //Draw Roomservice Cart Items
+ try {
+ let _elRsMnItems = _elRsMnRoot.children(`.items`);
+
+ // Delete elements under room service item table
+
+ if (_elRsMnItems.children('table').children('tr').length) {
+ _elRsMnItems.children('table').children('tr').remove();
+ }
+
+ let _eltbl_rs_items = _elRsMnItems.children('.table#item_list');
+ for (let _idx = 1; _idx <= _roomservice.children.length; _idx++) {
+ let _rsItem = _roomservice.children[_idx];
+
+ var _eltr_item = document.createElement('tr');
+ _eltr_item.setAttribute("id", _roomservice.children[_idx].id);
+ _eltr_item.setAttribute("ctz_idx", _idx);
+ //어메니티 아이탬 화면 드로잉
+ var _eldiv_item_ctz = document.createElement('div');
+ _eldiv_item_ctz.setAttribute("class", "products");
+
+ // Append Sub elements::title
+ let _elDiv_title = document.createElement('div');
+ _elDiv_title.setAttribute("id", "title");
+ _elDiv_title.textContent = _rsItem.title[_state.lang];
+ _eldiv_item_ctz.appendChild(_elDiv_title);
+
+ // Append Sub elements:: Price & Quantity
+ let _elDiv_details = document.createElement('div');
+ _elDiv_details.setAttribute("id", "details");
+ let _elDiv_price = document.createElement('div');
+ // Append Sub elements::price Value
+ _elDiv_price.setAttribute("id", "price");
+ _elDiv_price.textContent = _rsItem.price[_state.lang];
+ _elDiv_details.appendChild(_elDiv_price);
+
+ // Append Sub elements::Quantity
+ let _elDiv_qualtity = document.createElement('div');
+ _elDiv_qualtity.setAttribute("id", "quantity");
+ // Append Sub elements::Quantity:Title
+ let _elDiv_qualtityTitle = document.createElement('div');
+ _elDiv_qualtityTitle.setAttribute("id", "title");
+ _elDiv_qualtityTitle.textContent = _trTbl.ui.roomservice.title.quantity[_state.lang];
+ _elDiv_qualtity.appendChild(_elDiv_qualtityTitle);
+
+ // Append Sub elements::Quantity:Title
+ let _elDiv_qualtityValue = document.createElement('div');
+ _elDiv_qualtityValue.setAttribute("id", "value");
+ _elDiv_qualtityValue.textContent = "";
+ _elDiv_qualtity.appendChild(_elDiv_qualtityValue);
+
+ _elDiv_details.appendChild(_elDiv_qualtity);
+ _eldiv_item_ctz.appendChild(_elDiv_details);
+ _eltr_item.appendChild(_eldiv_item_ctz);
+ _eltbl_rs_items.append(_eltr_item);
+ }
+ // 첫번째 테이블 아애템에 active 클래스 추가 (플래그용으로 사용)
+ _elRsMnItems.children('table').children('tr').first().addClass('active');
+ } catch (_error) {
+ console.log(_error.message);
+ }
+
+ //Fill up roomservice important information such as free count and price, etc...
+ __uifxn_AppFull_DrawRoomserviceItem();
+
+ _elRsMnBtn.children('.order').text(_trTbl.ui.roomservice.title.order[_state.lang]);
+ _elRsMnBtn.children('.cancel').text(_trTbl.ui.roomservice.title.cancel[_state.lang]);
+ _elRsMnBtn.children('.details').text(_trTbl.ui.roomservice.title.carts[_state.lang]);
+
+ // HOTKEY정보를 state에 기록
+ if (!(_roomservice.button in _state.hotkey.mm)) {
+ _state.hotkey.mm[_roomservice.button] = {
+ 'type': "roomservice",
+ "status": {
+ "focus": "table",
+ "last_CartTbl_idx": 0,
+ "last_CartBtn_idx": null,
+ "last_OrderTbl_idx": 0,
+ }
+ };
+ }
+
+ if (_elRsMnRoot.css('box-shadow') == 'none') {
+ $('.popup .roomservice .menu').css('box-shadow', '0px 0px 30px rgba(0, 0, 0, 1)');
+ $('.popup .roomservice').animate({ backgroundColor: 'rgba(46,46,46,1.0)' }, 200, function() { $('.popup .roomservice .description').show() });
+ }
+
+ //Activated된 테이블 레코드의 ID속성값 읽어오기
+ let _ActiveItemID = _elRsMnRoot.children(`.items`).children('table').children('tr.active').prop('id');
+ //Description
+ _elRsMnDesc.children('.rstitle').text(__fxn_fmvalue(_roomservice.children, "title", _ActiveItemID)[_state.lang]);
+ _elRsMnDesc.children('.rscomment').text(__fxn_fmvalue(_roomservice.children, "description", _ActiveItemID)[_state.lang]);
+ _elRsMnDesc.children('.image').css('background-image', 'url(' + __fxn_fmvalue(_roomservice.children, "thumbnails", _ActiveItemID).files[_state.lang][1].download + ')');
+ }
+
+
+ /**
+ * HotelTV UI[AppFull] Wrapper Function::> room service handling function
+ * @param {boolean} e event
+ */
+ async function __uifxn_AppFull_HandleRoomservice(_evt, _isFlushCart, _isDoOrder) {
+ let _state = HotelTV.state;
+ let _trTbl = HotelTV.translation;
+ let _opening = HotelTV.opening;
+ let _roomservice = null;
+ let _carts = HotelTV.carts.roomservice;
+ let _scrollTopVal = 0;
+ let _elRsRoot = $(`.popup .roomservice`);
+ let _elRsMnRoot = $(`.popup .roomservice .menu`);
+ let _elRsMnItems = _elRsMnRoot.children('.items');
+ let _elRsMnBtn = _elRsMnRoot.children('.buttons');
+ let _elRsODRoot = _elRsMnRoot.children('.order-details');
+ let _elRsMnDesc = $(`.popup .roomservice .description`);
+
+ const _checkEmptyOrder = function(_object) {
+ for (__j = 1; __j <= _object.length; __j++) {
+ if (_object[__j].id) {
+ return false;
+ }
+ }
+ return true;
+ }
+
+ const __fxn_fmvalue = function(_object, _key, _itemID) {
+ for (__j = 1; __j <= _object.length; __j++) {
+ if (_object[__j].id == _itemID) {
+ return _object[__j][_key];
+ }
+ }
+ }
+
+ if (!_opening.roomService) {
+ return;
+ }
+ _roomservice = _opening.roomService;
+
+ if (_evt == "up") {
+ if (_state.hotkey.mm[_roomservice.button].status.focus == "table") {
+ let activeTableRow = _elRsMnItems.children('table').children('tr.active').prev(".table tr");
+ if (activeTableRow.length) {
+ _elRsMnItems.children('table').children('tr.active').removeClass("active");
+ activeTableRow.addClass('active');
+ _state.hotkey.mm[_roomservice.button].status.last_CartTbl_idx = activeTableRow.prop('rowIndex');
+
+ _scrollTopVal = activeTableRow.prop('scrollHeight') * _state.hotkey.mm[_roomservice.button].status.last_CartTbl_idx;
+ _elRsMnItems.animate({ scrollTop: _scrollTopVal }, 200);
+
+ //Activated된 테이블 레코드의 ID속성값 읽어오기
+ let _ActiveItemID = activeTableRow.prop('id');
+ //Description
+ _elRsMnDesc.children('.rstitle').text(__fxn_fmvalue(_roomservice.children, "title", _ActiveItemID)[_state.lang]);
+ _elRsMnDesc.children('.rscomment').text(__fxn_fmvalue(_roomservice.children, "description", _ActiveItemID)[_state.lang]);
+ _elRsMnDesc.children('.image').css('background-image', 'url(' + __fxn_fmvalue(_roomservice.children, "thumbnails", _ActiveItemID).files[_state.lang][1].download + ')');
+ }
+
+ if (_elRsMnRoot.css('box-shadow') == 'none') {
+ _elRsMnRoot.css('box-shadow', '0px 0px 30px rgba(0, 0, 0, 1)');
+ _elRsRoot.animate({ backgroundColor: 'rgba(46,46,46,1.0)' }, 200, function() {
+ _elRsMnDesc.children('.title').text(__fxn_fmvalue(_roomservice, "title", activeTableRow.prop('id'))[_state.lang]);
+ _elRsMnDesc.show()
+ });
+ }
+ } else if (_state.hotkey.mm[_roomservice.button].status.focus == "button") {
+ _elRsMnBtn.children('div').removeClass("active");
+ if (_state.hotkey.mm[_roomservice.button].status.last_CartBtn_idx == "details") {
+ _state.hotkey.mm[_roomservice.button].status.last_CartBtn_idx = "cancel";
+ _elRsMnBtn.children('div.cancel').addClass("active");
+
+ if (_elRsMnRoot.css('box-shadow') != 'none') {
+ _elRsMnRoot.css('box-shadow', 'none');
+ _elRsRoot.animate({ backgroundColor: 'rgba(46,46,46,0.0)' }, 200, function() { _elRsMnDesc.hide() });
+ }
+ } else if (_state.hotkey.mm[_roomservice.button].status.last_CartBtn_idx == "cancel") {
+ if (_checkEmptyOrder(_carts.items) == false) {
+ _state.hotkey.mm[_roomservice.button].status.last_CartBtn_idx = "order";
+ _elRsMnBtn.children('div.order').addClass("active");
+
+ if (_elRsMnRoot.css('box-shadow') != 'none') {
+ _elRsMnRoot.css('box-shadow', 'none');
+ _elRsRoot.animate({ backgroundColor: 'rgba(46,46,46,0.0)' }, 200, function() { _elRsMnDesc.hide() });
+ }
+ } else {
+ _state.hotkey.mm[_roomservice.button].status.last_CartBtn_idx = null;
+ _state.hotkey.mm[_roomservice.button].status.focus = "table";
+ _elRsMnItems.children('table').children('tr').eq(_state.hotkey.mm[_roomservice.button].status.last_CartTbl_idx).addClass('active');
+
+ //Activated된 테이블 레코드의 ID속성값 읽어오기
+ let _ActiveItemID = _elRsMnItems.children('table').children('tr.active').prop('id');
+ //Description
+ _elRsMnDesc.children('.rstitle').text(__fxn_fmvalue(_roomservice.children, "title", _ActiveItemID)[_state.lang]);
+ _elRsMnDesc.children('.rscomment').text(__fxn_fmvalue(_roomservice.children, "description", _ActiveItemID)[_state.lang]);
+ _elRsMnDesc.children('.image').css('background-image', 'url(' + __fxn_fmvalue(_roomservice.children, "thumbnails", _ActiveItemID).files[_state.lang][1].download + ')');
+
+ if (_elRsMnRoot.css('box-shadow') == 'none') {
+ _elRsMnRoot.css('box-shadow', '0px 0px 30px rgba(0, 0, 0, 1)');
+ _elRsRoot.animate({ backgroundColor: 'rgba(46,46,46,1.0)' }, 200, function() { _elRsMnDesc.show() });
+ }
+ }
+ } else {
+ _state.hotkey.mm[_roomservice.button].status.last_CartBtn_idx = null;
+ _state.hotkey.mm[_roomservice.button].status.focus = "table";
+ _elRsMnItems.children('table').children('tr').eq(_state.hotkey.mm[_roomservice.button].status.last_CartTbl_idx).addClass('active');
+ //Activated된 테이블 레코드의 ID속성값 읽어오기
+ let _ActiveItemID = _elRsMnItems.children('table').children('tr.active').prop('id');
+ //Description
+ _elRsMnDesc.children('.rstitle').text(__fxn_fmvalue(_roomservice.children, "title", _ActiveItemID)[_state.lang]);
+ _elRsMnDesc.children('.rscomment').text(__fxn_fmvalue(_roomservice.children, "description", _ActiveItemID)[_state.lang]);
+ _elRsMnDesc.children('.image').css('background-image', 'url(' + __fxn_fmvalue(_roomservice.children, "thumbnails", _ActiveItemID).files[_state.lang][1].download + ')');
+
+ if (_elRsMnRoot.css('box-shadow') == 'none') {
+ _elRsMnRoot.css('box-shadow', '0px 0px 30px rgba(0, 0, 0, 1)');
+ _elRsRoot.animate({ backgroundColor: 'rgba(46,46,46,1.0)' }, 200, function() {
+ _elRsMnDesc.show()
+ });
+ }
+ }
+ } else if (_state.hotkey.mm[_roomservice.button].status.focus == "order_details") {
+
+ let activeTableRow = _elRsODRoot.children('.items').children('table').children('tr.active').prev(".table tr");
+ if (activeTableRow.length) {
+ _elRsODRoot.children('.items').children('table').children('tr.active').removeClass("active");
+ activeTableRow.addClass('active');
+ _state.hotkey.mm[_roomservice.button].status.last_OrderTbl_idx = activeTableRow.prop('rowIndex');
+ _scrollTopVal = activeTableRow.prop('scrollHeight') * _state.hotkey.mm[_roomservice.button].status.last_OrderTbl_idx;
+ _elRsODRoot.children('.items').animate({ scrollTop: _scrollTopVal }, 200);
+ }
+
+ if (_elRsMnRoot.css('box-shadow') != 'none') {
+ _elRsMnRoot.css('box-shadow', 'none');
+ _elRsRoot.animate({ backgroundColor: 'rgba(46,46,46,0.0)' }, 200, function() { _elRsMnDesc.hide() });
+ }
+ }
+ console.log(`STATUS::> ${JSON.stringify(_state.hotkey.mm[_roomservice.button].status)}`);
+ } else if (_evt == "down") {
+ if (_state.hotkey.mm[_roomservice.button].status.focus == "table") {
+ let activeTableRow = _elRsMnItems.children('table').children('tr.active').next(".table tr");
+ if (activeTableRow.length) {
+ _elRsMnItems.children('table').children('tr.active').removeClass("active");
+ activeTableRow.addClass('active');
+ _state.hotkey.mm[_roomservice.button].status.last_CartTbl_idx = activeTableRow.prop('rowIndex');
+ _scrollTopVal = activeTableRow.prop('scrollHeight') * _state.hotkey.mm[_roomservice.button].status.last_CartTbl_idx;
+ _elRsMnItems.animate({ scrollTop: _scrollTopVal }, 200);
+
+ //Activated된 테이블 레코드의 ID속성값 읽어오기
+ let _ActiveItemID = activeTableRow.prop('id');
+ //Description
+ _elRsMnDesc.children('.rstitle').text(__fxn_fmvalue(_roomservice.children, "title", _ActiveItemID)[_state.lang]);
+ _elRsMnDesc.children('.rscomment').text(__fxn_fmvalue(_roomservice.children, "description", _ActiveItemID)[_state.lang]);
+ _elRsMnDesc.children('.image').css('background-image', 'url(' + __fxn_fmvalue(_roomservice.children, "thumbnails", _ActiveItemID).files[_state.lang][1].download + ')');
+
+ if (_elRsMnRoot.css('box-shadow') == 'none') {
+ _elRsMnRoot.css('box-shadow', '0px 0px 30px rgba(0, 0, 0, 1)');
+ _elRsRoot.animate({ backgroundColor: 'rgba(46,46,46,1.0)' }, 200, function() { _elRsMnDesc.show() });
+ }
+ } else {
+ _state.hotkey.mm[_roomservice.button].status.focus = "button";
+ if (!_state.hotkey.mm[_roomservice.button].status.last_CartBtn_idx) {
+ _elRsMnItems.children('table').children('tr.active').removeClass("active");
+ _elRsMnBtn.children('div').removeClass("active");
+ if (_checkEmptyOrder(_carts.items) == false) {
+ _state.hotkey.mm[_roomservice.button].status.last_CartBtn_idx = "order";
+ _elRsMnBtn.children('div.order').addClass("active");
+ } else {
+ _state.hotkey.mm[_roomservice.button].status.last_CartBtn_idx = "cancel";
+ _elRsMnBtn.children('div.cancel').addClass("active");
+ }
+ }
+
+ if (_elRsMnRoot.css('box-shadow') != 'none') {
+ _elRsMnRoot.css('box-shadow', 'none');
+ _elRsRoot.animate({ backgroundColor: 'rgba(46,46,46,0.0)' }, 200, function() { _elRsMnDesc.hide() });
+ }
+ }
+ } else if (_state.hotkey.mm[_roomservice.button].status.focus == "button") {
+ if (_state.hotkey.mm[_roomservice.button].status.last_CartBtn_idx == "order") {
+ _elRsMnBtn.children('div').removeClass("active");
+ _state.hotkey.mm[_roomservice.button].status.last_CartBtn_idx = "cancel";
+ _elRsMnBtn.children('div.cancel').addClass("active");
+ } else if (_state.hotkey.mm[_roomservice.button].status.last_CartBtn_idx == "cancel") {
+ _elRsMnBtn.children('div').removeClass("active");
+ _state.hotkey.mm[_roomservice.button].status.last_CartBtn_idx = "details";
+ _elRsMnBtn.children('div.details').addClass("active");
+ }
+
+ if (_elRsMnRoot.css('box-shadow') != 'none') {
+ _elRsMnRoot.css('box-shadow', 'none');
+ _elRsRoot.animate({ backgroundColor: 'rgba(46,46,46,0.0)' }, 200, function() { _elRsMnDesc.hide() });
+ }
+ } else if (_state.hotkey.mm[_roomservice.button].status.focus == "order_details") {
+ let activeTableRow = _elRsODRoot.children('.items').children('table').children('tr.active').next(".table tr");
+ if (activeTableRow.length) {
+ _elRsODRoot.children('.items').children('table').children('tr.active').removeClass("active");
+ activeTableRow.addClass('active');
+ _state.hotkey.mm[_roomservice.button].status.last_OrderTbl_idx = activeTableRow.prop('rowIndex');
+ _scrollTopVal = activeTableRow.prop('scrollHeight') * _state.hotkey.mm[_roomservice.button].status.last_OrderTbl_idx;
+ _elRsODRoot.children('.items').animate({ scrollTop: _scrollTopVal }, 200);
+ }
+
+ if (_elRsMnRoot.css('box-shadow') != 'none') {
+ _elRsMnRoot.css('box-shadow', 'none');
+ _elRsRoot.animate({ backgroundColor: 'rgba(46,46,46,0.0)' }, 200, function() { _elRsMnDesc.hide() });
+ }
+ }
+ console.log(`STATUS::> ${JSON.stringify(_state.hotkey.mm[_roomservice.button].status)}`);
+ } else if (_evt == "enter") {
+ _state.hotkey.mm[_roomservice.button].status.focus = "order_details";
+ } else if (_evt == "reset") {
+ _state.hotkey.mm[_roomservice.button].status = {
+ "focus": "table",
+ "last_CartTbl_idx": 0,
+ "last_CartBtn_idx": null,
+ "last_OrderTbl_idx": 0,
+ };
+ _elRsMnBtn.children('div').removeClass("active");
+ _elRsMnItems.children('table').children('tr').removeClass("active");
+ _elRsMnItems.children('table').children('tr').first().addClass('active');
+ _elRsODRoot.children('.items').children('table').children('tr').removeClass("active");
+ _elRsODRoot.children('.items').children('table').children('tr').first().addClass('active');
+
+ if (_elRsMnRoot.css('box-shadow') == 'none') {
+ $('.popup .roomservice .menu').css('box-shadow', '0px 0px 30px rgba(0, 0, 0, 1)');
+ $('.popup .roomservice').animate({ backgroundColor: 'rgba(46,46,46,1.0)' }, 200, function() { $('.popup .roomservice .description').show() });
+ }
+
+ //Activated된 테이블 레코드의 ID속성값 읽어오기
+ let _ActiveItemID = _elRsMnRoot.children(`.items`).children('table').children('tr.active').prop('id');
+ //Description
+ _elRsMnDesc.children('.rstitle').text(__fxn_fmvalue(_roomservice.children, "title", _ActiveItemID)[_state.lang]);
+ _elRsMnDesc.children('.rscomment').text(__fxn_fmvalue(_roomservice.children, "description", _ActiveItemID)[_state.lang]);
+ _elRsMnDesc.children('.image').css('background-image', 'url(' + __fxn_fmvalue(_roomservice.children, "thumbnails", _ActiveItemID).files[_state.lang][1].download + ')');
+
+ // Flush CART
+ if (_isFlushCart == true && HotelTV.carts.roomservice.items) {
+ let _cartsItems = HotelTV.carts.roomservice.items;
+ for (_k = 1; _k <= _cartsItems.length; _k++) {
+ if (_cartsItems[_k].id) {
+ try {
+ let _result = await HotelTV.api.DeleteRoomserviceCarts(_cartsItems[_k].id);
+ if (_result) {
+ console.log(`Success to flush CARTID::> ${_cartsItems[_k].id}`);
+ } else {
+ console.log(`Fail to flush CARTID::> ${_cartsItems[_k].id}`);
+ }
+ } catch (_error) {
+ console.log(`Fail to call API::> ${_error}`);
+ }
+ }
+ }
+ __uifxn_AppFull_DrawRoomserviceItem();
+ }
+
+ // Order
+ if (_isDoOrder == true && HotelTV.carts.roomservice.items) {
+ try {
+ let _result = await HotelTV.api.PutRoomserviceOrders();
+ if (_result) {
+ console.log(`Success to order CARTID::>`);
+ __uifxn_AppFull_DrawRoomserviceItem();
+ } else {
+ console.log(`Fail to order CARTID::>`);
+ }
+ } catch (_error) {
+ console.log(`Fail to call API::> ${_error}`);
+ }
+ }
+ } else if (_evt == "add") {
+ if (_state.hotkey.mm[_roomservice.button].status.focus == "table") {
+ let activedTableRow = _elRsMnItems.children('table').children('tr.active');
+ let _sel_itemID = activedTableRow.attr('id');
+ try {
+ let _result = await HotelTV.api.PutRoomserviceCarts(_sel_itemID, 1);
+ if (_result) {
+ __uifxn_AppFull_DrawRoomserviceItem();
+ }
+ } catch (_error) {
+ console.log(`Fail to call API::> ${_error}`);
+ }
+ }
+ } else if (_evt == "del") {
+ if (_state.hotkey.mm[_roomservice.button].status.focus == "table") {
+ let activedTableRow = _elRsMnItems.children('table').children('tr.active');
+ let _sel_itemID = activedTableRow.attr('id');
+ try {
+ let _result = await HotelTV.api.PutRoomserviceCarts(_sel_itemID, -1);
+ if (_result) {
+ __uifxn_AppFull_DrawRoomserviceItem();
+ }
+ } catch (_error) {
+ console.log(`Fail to call API::> ${_error}`);
+ }
+ }
+ }
+ }
+
+ /**
+ * HotelTV UI[AppFull] Wrapper Function::> build news
+ * @param {boolean} e event
+ */
+ function __uifxn_AppFull_BldNews() {
+ let _state = HotelTV.state;
+ let _newsInfo = HotelTV.news;
+
+ if (!(_newsInfo) || _newsInfo.length == 0) {
+ $('.news').hide();
+ } else {
+ let _hndlNewsTicker = $('.news>.newsctz #hoteltv-news-ticker');
+ if (_hndlNewsTicker.children().length == 0) {
+ let sz_li_news = "";
+ for (let _nwsIdx = 1; _nwsIdx <= _newsInfo.length; _nwsIdx++) {
+ if (_newsInfo[_nwsIdx].logo.download != "") {
+ sz_li_news += `
${_newsInfo[_nwsIdx].content[_state.lang]}`;
+ } else {
+ sz_li_news += `${_newsInfo[_nwsIdx].content[_state.lang]}`;
+ }
+ }
+ _hndlNewsTicker.html(sz_li_news);
+ _hndlNewsTicker.webTicker({
+ height: '38px',
+ speed: 100
+ });
+ } else {
+ let sz_li_news = "";
+ for (let _nwsIdx = 1; _nwsIdx <= _newsInfo.length; _nwsIdx++) {
+ if (_newsInfo[_nwsIdx].logo.download != "") {
+ if (_newsInfo[_nwsIdx].multilanguage == true) {
+ sz_li_news += `
${_newsInfo[_nwsIdx].content[_state.lang]}`;
+ } else {
+ sz_li_news += `
${_newsInfo[_nwsIdx].content.default}`;
+ }
+ } else {
+ if (_newsInfo[_nwsIdx].multilanguage == true) {
+ sz_li_news += `${_newsInfo[_nwsIdx].content[_state.lang]}`;
+ } else {
+ sz_li_news += `${_newsInfo[_nwsIdx].content.default}`;
+ }
+ }
+ }
+ $(".news>.newsctz #hoteltv-news-ticker").webTicker('update', sz_li_news,
+ 'swap',
+ true,
+ false
+ );
+ }
+ }
+ }
+
+
+
+
+ /**
+ * HotelTV UI[AppFull] Wrapper Function::> received event handling function
+ * @param {boolean} e event
+ */
+ function __uifxn_AppFull_OnKeyDnEvt_SmSel(_evt) {
+ let _state = HotelTV.state;
+ let _sminfo = HotelTV.tvguide.program[_state.menu.main.cur].children;
+ //console.log(`Evnt: ${_evt.item.index} Of ${_evt.item.count} page::> ${_evt.page.index} of ${_evt.page.count}`);
+
+ $('#lst_smbg').trigger("to.owl.carousel", [_evt.page.index, 1000, true]);
+ }
+
+ /**
+ * HotelTV UI[AppFull] Wrapper Function::> Get EPG Info by EPG id
+ * @param {dictionary} _evt event information
+ */
+ function __uifxn_AppFull_GetEpgInfoById(_id) {
+ let _epgInfo = HotelTV.epg;
+ let _tm_cur = new Date();
+
+ if (_epgInfo == 'undefined' || _epgInfo == null) {
+ return null;
+ }
+
+ if (Object.keys(_epgInfo).includes('schedules') != true || Object.keys(_epgInfo).includes('channels') != true) {
+ return null;
+ }
+
+ //Find out epg schedule id
+ let _epg_schId = null;
+ for (let _j in _epgInfo.channels) {
+ if (_epgInfo.channels[_j].name == _id) {
+ _epg_schId = _epgInfo.channels[_j].id;
+ }
+ }
+
+ // EPG SHEDULE ID를 찾을 수 없으므로, null 반환.
+ if (_epg_schId == null) { return null; }
+
+ let _epg_prom_info = null;
+ if (Object.keys(_epgInfo.schedules).includes(_epg_schId) != true) {
+ return null;
+ }
+ _epg_prom_info = _epgInfo.schedules[_epg_schId];
+
+ let _rtn_epg = null;
+ for (let _j in _epg_prom_info) {
+ let _schTm = new Date();
+
+ if (_epg_prom_info[_j].time.length != 5) {
+ console.log("Flight Schedule org time is NULL");
+ } else {
+ _schTm.setHours(Number(_epg_prom_info[_j].time.charAt(0) + _epg_prom_info[_j].time.charAt(1)));
+ _schTm.setMinutes(Number(_epg_prom_info[_j].time.charAt(3) + _epg_prom_info[_j].time.charAt(4)));
+ }
+
+ let _tdiff_cur = Math.round((_schTm - _tm_cur) / 60000); //Time diff in minuate
+ if (_rtn_epg == null) {
+ _rtn_epg = _epg_prom_info[_j];
+ }
+
+ if (_tdiff_cur > 0) {
+ return _rtn_epg;
+ }
+ _rtn_epg = _epg_prom_info[_j];
+ //console.log("CHNAME::>" + _id + " TDiff::> " + _tdiff_cur);
+ }
+ return _rtn_epg;
+ }
+
+ /**
+ * HotelTV UI[AppFull] Wrapper Function::> TV Channel manager ui show/hide
+ */
+ function __uifxn_AppFull_TVChMngrUi() {
+ let _state = HotelTV.state;
+ let _tm_diff_ms = 0;
+
+ if (_lastTm.keyevt == null) {
+ return;
+ }
+
+ let _tm_cur = new Date();
+ _tm_diff_ms = Math.floor(_tm_cur.getTime() - _lastTm.keyevt.getTime());
+ //마지막 KEY 이벤트 수신 시간 갱신
+ //console.log(`KeyDn Event Recoreded::> ${_lastTm.keyevt} TMDiff::> ${_tm_diff_ms}`);
+
+ // TV Channel UI 지속 시간 8초
+ if (_tm_diff_ms < 8000) {
+ let el_width = $('.main .tv .bg .owl-carousel .owl-stage-outer .owl-stage .item').width();
+ el_width = (el_width + 100) * -1;
+ if ($('.main .tv .bg .owl-carousel .owl-stage-outer').position().left == el_width) {
+ $('.main .tv .bg .owl-carousel .owl-stage-outer').stop().animate({ left: '0px' }, 800, function() {
+ _state.menu.stage = "tvCtgShow";
+ });
+ }
+ } else {
+ if ($('.main .tv .bg .owl-carousel .owl-stage-outer').position().left == 0) {
+ _state.menu.stage = "tvCtgHide";
+ let el_width = $('.main .tv .bg .owl-carousel .owl-stage-outer .owl-stage .item').width();
+ el_width = (el_width + 100) * -1;
+ $('.main .tv .bg .owl-carousel .owl-stage-outer').stop().animate({ left: el_width.toString() + 'px' }, 800);
+ }
+ }
+ }
+
+ /**
+ * HotelTV UI[AppFull] Wrapper Function::> update message selection on mypage
+ * @param {string} _action parameter
+ */
+ function __uifxn_AppFull_MyPageSelectMessage(_action) {
+ const _state = HotelTV.state;
+
+ if (!(HotelTV.message)) {
+ console.log("INFO::> No messages");
+ return;
+ }
+
+ const _msg = HotelTV.message;
+ const _mmIdx = _state.menu.main.cur;
+ const _mmInfo = HotelTV.tvguide.program[_mmIdx];
+ let _state_mypage = _state.menu.main[_mmIdx];
+
+ if (_mmInfo.children[_state_mypage.cur].type == 'message') {
+ const _total_cnt = _state_mypage['message']['cnt'];
+ let _cur_idx = _state_mypage['message']['cur'];
+ //mp_msg_tblrec tr엘리멘트들을 Query
+ let _el_target = $('.main>.mypage>.bg>.owl-carousel .owl-item #mp_msg_tblrec tbody');
+ if (_action == "up") {
+ if ((_cur_idx - 1) < 0) {
+ _cur_idx = 0;
+ } else {
+ _cur_idx -= 1;
+ }
+
+ $('.main>.mypage>.bg>.owl-carousel .owl-item #mp_msg_tblrec tr').removeClass('focus');
+ $('.main>.mypage>.bg>.owl-carousel .owl-item #mp_msg_tblrec tr').filter("[msgidx='" + _cur_idx.toString() + "']").addClass('focus');
+ _state.menu.main[_mmIdx]['message']['cur'] = _cur_idx;
+
+ if ((_cur_idx >= 3) && (_cur_idx < (_total_cnt - 3))) {
+ _el_target.stop().animate({ scrollTop: ((_cur_idx - 3) * 52).toString() }, 500, function() {
+ console.log("SCROLL DONE>>>1");
+ });
+ }
+ } else if (_action == "down") {
+ if ((_cur_idx + 1) > (_total_cnt - 1)) {
+ _cur_idx = (_total_cnt - 1);
+ } else {
+ _cur_idx += 1;
+ }
+ $('.main>.mypage>.bg>.owl-carousel .owl-item #mp_msg_tblrec tr').removeClass('focus');
+ $('.main>.mypage>.bg>.owl-carousel .owl-item #mp_msg_tblrec tr').filter("[msgidx='" + _cur_idx.toString() + "']").addClass('focus');
+ _state.menu.main[_mmIdx]['message']['cur'] = _cur_idx;
+
+ if ((_cur_idx > 3) && (_cur_idx < (_total_cnt - 2))) {
+ _el_target.stop().animate({ scrollTop: ((_cur_idx - 3) * 52).toString() }, 500, function() {
+ console.log("SCROLL DONE>>>2");
+ });
+ }
+ }
+ } else {
+ console.log("ERROR::> No centered Item");
+ }
+ }
+
+
+ /**
+ * HotelTV UI[AppFull] Wrapper Function::> My Page
+ */
+ function __uifxn_AppFull_BuildMyPage() {
+ const _trTbl = HotelTV.translation;
+ const _state = HotelTV.state;
+ const _msg = HotelTV.message;
+ const _guest = HotelTV.guestinfo;
+ const _hotel = HotelTV.hotelinfo;
+ const _mmIdx = _state.menu.main.cur;
+ const _mpinfo = HotelTV.tvguide.program[_mmIdx].children;
+
+ if (!(_mmIdx in _state.menu.main)) {
+ _state.menu.main[_mmIdx] = {
+ 'cnt': 0,
+ 'cur': null,
+ 'prev': null,
+ };
+ _state.menu.main[_mmIdx].cnt = _mpinfo.length;
+ }
+
+ // 초기 메인 메뉴 KEY설정
+ _state.menu.stage = "preparing_mypage";
+ if (_state.menu.main[_mmIdx].cur == null) {
+ _state.menu.main[_mmIdx].cur = Object.keys(_mpinfo)[0];
+ }
+
+ // MYPAGE 메뉴 셀렉터 노드를 동적으로 구성
+ let _div_mp_slist = document.querySelector('#lst_mypagesel');
+ for (let _i = 1; _i <= _mpinfo.length; _i++) {
+ let _div_mpsel_item = document.createElement('div');
+ _div_mpsel_item.className = 'item';
+ _div_mpsel_item.id = 'mpsel_' + _mpinfo[_i].id;
+ _div_mpsel_item.setAttribute("mpid", _mpinfo[_i].id);
+
+ // Append Sub elements::title
+ let _mp_item_title = document.createElement('div');
+ _mp_item_title.setAttribute("id", "mp_item_title");
+ if (_mpinfo.length > 1) {
+ _mp_item_title.textContent = _mpinfo[_i].title[_state.lang];
+
+ // Append Sub elements::icon
+ let _mp_item_icon = document.createElement('div');
+ _mp_item_icon.setAttribute("id", "mp_item_icon");
+ let _sz_styleOpt = "--icon_unfocus: url(" + _mpinfo[_i].unfocusIcon.file.download + "); ";
+ _sz_styleOpt += "--icon_focus: url(" + _mpinfo[_i].focusIcon.file.download + "); ";
+ _sz_styleOpt += "background-repeat: no-repeat; background-position: center bottom; background-size: 100% 100%; ";
+ _mp_item_icon.setAttribute("style", _sz_styleOpt);
+
+ _div_mpsel_item.appendChild(_mp_item_icon);
+ } else {
+
+ }
+ _div_mpsel_item.appendChild(_mp_item_title);
+ _div_mp_slist.appendChild(_div_mpsel_item);
+ }
+
+ // MYPAGE 메뉴 백그라운드 노드를 동적으로 구성
+ let _div_mp_bglist = document.querySelector('#lst_mypagebg');
+ for (let _i = 1; _i <= _mpinfo.length; _i++) {
+ let _div_mpbg_item = document.createElement('div');
+ _div_mpbg_item.className = 'item';
+ _div_mpbg_item.id = 'mpbg_' + _mpinfo[_i].id;
+
+ let _sz_styleOpt = "background-image: url(" + _mpinfo[_i].background.file.download + "); ";
+ _sz_styleOpt += "background-repeat: no-repeat; background-position: center center; background-size: contain ";
+ _div_mpbg_item.setAttribute("style", _sz_styleOpt);
+
+ if (_mpinfo[_i].type == "accommodation") {
+ let _accomo_title = document.createElement('div');
+ _accomo_title.setAttribute("id", "mp_accomo_title");
+ _accomo_title.textContent = _guest.name + _trTbl.ui.mypage.accmodation.title.title[_state.lang];
+ _div_mpbg_item.appendChild(_accomo_title);
+
+ let _accomo_info = document.createElement('div');
+ _accomo_info.setAttribute("id", "mp_accomo_infowin");
+
+ const _accmo_item_list = ["accmodation_gstname", "accmodation_rsvcode", "accmodation_hotel", "accmodation_bed_type", "accmodation_room_num", "accmodation_checkin", "accmodation_checkout"];
+ for (let _j = 0; _j < _accmo_item_list.length; _j++) {
+ let __info_item = document.createElement('div');
+ __info_item.className = 'accmoinf_item';
+ switch (_accmo_item_list[_j]) {
+ case 'accmodation_gstname':
+ __info_item.innerHTML = ``;
+ __info_item.innerHTML += `${_guest.name}`;
+ break;
+ case 'accmodation_rsvcode':
+ __info_item.innerHTML = ``;
+ __info_item.innerHTML += `${_guest.id}`;
+ break;
+ case 'accmodation_hotel':
+ __info_item.innerHTML = ``;
+ __info_item.innerHTML += `${_hotel.name}`;
+ break;
+ case 'accmodation_bed_type':
+ __info_item.innerHTML = ``;
+ __info_item.innerHTML += `${_guest.roomtype}`;
+ break;
+ case 'accmodation_room_num':
+ __info_item.innerHTML = ``;
+ __info_item.innerHTML += `${_guest.room}`;
+ break;
+ case 'accmodation_checkin':
+ __info_item.innerHTML = ``;
+ __info_item.innerHTML += `${_guest.checkIn}`;
+ break;
+ case 'accmodation_checkout':
+ __info_item.innerHTML = ``;
+ __info_item.innerHTML += `${_guest.checkOu}`;
+ break;
+ }
+ _accomo_info.appendChild(__info_item);
+ }
+ _div_mpbg_item.appendChild(_accomo_info);
+
+ //Hotel info win
+ let _hotel_info = document.createElement('div');
+ _hotel_info.setAttribute("id", "mp_hotel_infowin");
+
+ const _hotelinfo_item_list = ["address", "custominquiry", "resvinquiry"];
+ for (let _j = 0; _j < _hotelinfo_item_list.length; _j++) {
+ let __info_item = document.createElement('div');
+ __info_item.className = 'hotelinfo_item';
+ switch (_hotelinfo_item_list[_j]) {
+ case 'address':
+ __info_item.innerHTML = `${_trTbl.ui.mypage.accmodation.title.address[_state.lang]}`;
+ __info_item.innerHTML += `${_hotel.address[_state.lang]}`;
+ break;
+ case 'custominquiry':
+ __info_item.innerHTML = `${_trTbl.ui.mypage.accmodation.title.custominquiry[_state.lang]}`;
+ __info_item.innerHTML += `${_hotel.inquiry.custom.email}`;
+ __info_item.innerHTML += `${_hotel.inquiry.custom.phone[_state.lang]}`;
+ break;
+ case 'resvinquiry':
+ __info_item.innerHTML = `${_trTbl.ui.mypage.accmodation.title.resvinquiry[_state.lang]}`;
+ __info_item.innerHTML += `${_hotel.inquiry.reservation.email}`;
+ __info_item.innerHTML += `${_hotel.inquiry.reservation.phone[_state.lang]}`;
+ break;
+ }
+ _hotel_info.appendChild(__info_item);
+ }
+ _div_mpbg_item.appendChild(_hotel_info);
+
+ } else if (_mpinfo[_i].type == "message") {
+ // 메시지 상태 오브젝트 초기화
+ if (!("message" in _state.menu.main[_mmIdx])) {
+ _state.menu.main[_mmIdx]['message'] = {
+ 'cnt': 0,
+ 'cur': null,
+ 'prev': null,
+ };
+ _state.menu.main[_mmIdx]['message'].cnt = _msg.length;
+ }
+
+
+ let _msg_title = document.createElement('div');
+ _msg_title.setAttribute("id", "mp_message_title");
+ let _msg_unread_cnt = 0;
+ for (let _j = 1; _j <= _msg.length; _j++) {
+ if (_msg[_j].read == false) {
+ _msg_unread_cnt++;
+ }
+ }
+ _msg_title.textContent = _guest.name + _trTbl.ui.mypage.message.title.title[_state.lang].replace("_XX", _msg_unread_cnt.toString());
+ _div_mpbg_item.appendChild(_msg_title);
+
+ let _msg_table = document.createElement('div');
+ _msg_table.setAttribute("id", "mp_message_table");
+
+ let _msg_tblhdr = document.createElement('table');
+ _msg_tblhdr.setAttribute("id", "mp_msg_tblhdr");
+ _msg_tblhdr.innerHTML = '' +
+ '| ' + _trTbl.ui.mypage.message.title.table.num[_state.lang] + ' | ' +
+ '' + _trTbl.ui.mypage.message.title.table.title[_state.lang] + ' | ' +
+ '' + _trTbl.ui.mypage.message.title.table.from[_state.lang] + ' | ' +
+ '' + _trTbl.ui.mypage.message.title.table.date[_state.lang] + ' | ' +
+ '
';
+ _msg_table.appendChild(_msg_tblhdr);
+
+ let _msg_tblrec = document.createElement('table');
+ _msg_tblrec.setAttribute("id", "mp_msg_tblrec");
+ let _sz_innerHTML = '';
+ let _num_msgIdx = 0;
+ for (let _j = _msg.length; _j > 0; _j--) {
+ _sz_innerHTML += '';
+ if (_msg[_j].read == false) {
+ _sz_innerHTML += '| ' + _j.toString() + ' | ';
+ } else {
+ _sz_innerHTML += '' + _j.toString() + ' | ';
+ }
+ if (_msg[_j].multilanguage == false) {
+ _sz_innerHTML += '' + _msg[_j].title.default+' | ';
+ } else {
+ _sz_innerHTML += '' + _msg[_j].title[_state.lang] + ' | ';
+ }
+ _sz_innerHTML += '' + _msg[_j].from + ' | ';
+ _sz_innerHTML += '' + _msg[_j].createdAt + ' | ';
+ _sz_innerHTML += '
';
+ _num_msgIdx++;
+ }
+ _sz_innerHTML += '';
+ _msg_tblrec.innerHTML = _sz_innerHTML;
+ _msg_table.appendChild(_msg_tblrec);
+ _div_mpbg_item.appendChild(_msg_table);
+ }
+
+ _div_mp_bglist.appendChild(_div_mpbg_item);
+ }
+
+ _hndl_mpBg = $('#lst_mypagebg');
+ _hndl_mpBg.owlCarousel({
+ center: true,
+ items: 1, //Number of Items on Screen what you want
+ loop: true,
+ nav: false,
+ dots: false,
+ margin: 0,
+ smartSpeed: 700,
+ autoWidth: false,
+ mouseDrag: false,
+ touchDrag: false,
+ pullDrag: false,
+ freeDrag: false,
+ //MYPAGE는 항상 accommodation부터 시작
+ startPosition: 0,
+ });
+
+
+ _hndl_mpSel = $('#lst_mypagesel');
+ _hndl_mpSel.owlCarousel({
+ center: true,
+ items: 3, //Number of Items on Screen what you want
+ loop: true,
+ nav: false,
+ dots: true,
+ margin: 0,
+ smartSpeed: 700,
+ autoWidth: false,
+ mouseDrag: false,
+ touchDrag: false,
+ pullDrag: false,
+ freeDrag: false,
+ //MYPAGE는 항상 accommodation부터 시작
+ startPosition: 0,
+ });
+
+ $('.main .mypage').show();
+ $('.main .mypage .bg').show();
+
+ //메인 페이지->MyPage 페이지 화면 전환
+ $('.main .mypage .slider').show(function() {
+ $('.main').animate({ top: -1080, left: 0 }, 1000, function() {
+ $('.main .mm').fadeOut(1000);
+ $('#lst_mypagesel').trigger('translate.owl.carousel', [0]);
+
+ $(document.activeElement).keydown(function(event) { //attach event listener
+ if (_state.menu.stage == "mypage") {
+ if (event.keyCode == 37) {
+ $('#lst_mypagesel').trigger('prev.owl')
+ $('#lst_mypagebg').trigger('prev.owl')
+ } else if (event.keyCode == 39) {
+ $('#lst_mypagesel').trigger('next.owl')
+ $('#lst_mypagebg').trigger('next.owl')
+ } else if (event.keyCode == 38) {
+ //UP
+ __uifxn_AppFull_MyPageSelectMessage("up");
+ } else if (event.keyCode == 40) {
+ //DOWN
+ __uifxn_AppFull_MyPageSelectMessage("down");
+ } else if (event.keyCode == 13) {
+ const _mpinfo = HotelTV.tvguide.program[_mmIdx].children;
+ // 메시지 팝업 빌드 및 화면 전환
+ if (HotelTV.tvguide.program[_mmIdx].children[_state.menu.main[_mmIdx].cur].type == 'message') {
+ const _msginf = HotelTV.message;
+ let _cur_msglst_idx = _state.menu.main[_mmIdx]['message']['cur'];
+ // 현재 선택된 메시지의 디테일 정보 가져오기
+ let _cur_msgnum = $($('.main>.mypage>.bg>.owl-carousel .owl-item.center #mp_msg_tblrec tbody .focus')[0]).attr('msgnum');
+ // 마이페이지 메뉴에서 메시지를 선택하지 않고 엔터키를 누른경우
+ if (!(_cur_msgnum)) {
+ return;
+ }
+
+
+ let _cur_msgdesc = _msginf[_cur_msgnum];
+ // Message card 구성
+ switch (_state.lang) {
+ case 'ko-KR':
+ $('.popup>.mypage>.message').css('font-family', 'Nanum Pen Script');
+ $('.popup>.mypage>.message>#msg_ctz').css('font-size', '34px');
+ $('.popup>.mypage>.message>#title').css('font-size', '50px');
+ break;
+ case 'zh-CN':
+ $('.popup>.mypage>.message').css('font-family', 'Ma Shan Zheng');
+ $('.popup>.mypage>.message>#msg_ctz').css('font-size', '34px');
+ $('.popup>.mypage>.message>#title').css('font-size', '50px');
+ break;
+ case 'zh-TW':
+ $('.popup>.mypage>.message').css('font-family', 'Ma Shan Zheng');
+ $('.popup>.mypage>.message>#msg_ctz').css('font-size', '34px');
+ $('.popup>.mypage>.message>#title').css('font-size', '50px');
+ break;
+ default:
+ $('.popup>.mypage>.message').css('font-family', 'Parisienne');
+ $('.popup>.mypage>.message>#msg_ctz').css('font-size', '32px');
+ break;
+ }
+ $('.popup>.mypage>.message>#title').text(_cur_msgdesc.from);
+ if (_cur_msgdesc.multilanguage == true) {
+ $('.popup>.mypage>.message>#msg_ctz').html(_cur_msgdesc.content[_state.lang].replace(/(?:\r\n|\r|\n)/g, '
'));
+ } else {
+ $('.popup>.mypage>.message>#msg_ctz').html(_cur_msgdesc.content.default.replace(/(?:\r\n|\r|\n)/g, '
'));
+ }
+
+ //Back button
+ $('.popup>.mypage>.message>#btn_back').text(_trTbl.system.btn.back[_state.lang]);
+
+ //SHOW ANIMATION
+ if ($('.popup>.mypage>.message').css('display') == "none") {
+ _state.menu.stage = "popup_message_card";
+ $('.main>.mypage>.slider').animate({ top: 1080, left: 0 }, 1000, function() {
+ $('.popup>.mypage>.message').fadeIn(500);
+
+ //메시지 읽음 처리
+ HotelTV.api.SetMessageStatus(_cur_msgdesc._id);
+ $('.main>.mypage>.bg>.owl-carousel .owl-item #mp_msg_tblrec tr').filter("[msgidx='" + _cur_msglst_idx.toString() + "']").children('td#num').addClass('read');
+ });
+ }
+ }
+ } else if (event.keyCode == 461) {
+ // 메인 메뉴로 귀환
+ $(document.activeElement).off('keydown');
+ $('.main .mm').show(function() {
+ $('#lst_mmsel').trigger('refresh.owl.carousel', [0]);
+ });
+ $('.main').animate({ top: 0, left: 0 }, 1000, () => {
+ $('#lst_mypagesel').off('translate.owl.carousel');
+
+ $('#lst_mypagebg').owlCarousel('destroy');
+ $('#lst_mypagesel').owlCarousel('destroy');
+
+ $('.main .mypage .slider #lst_mypagesel div').remove();
+ $('.main .mypage .bg #lst_mypagebg div').remove();
+ $('.main .mypage').hide();
+ _hndl_mpSel = null;
+ _hndl_mpBg = null;
+ _state.menu.stage = "main"
+ setTimeout(function() {
+ __uifxn_AppFull_ShowMMHotKeyBtn(true);
+ }, 500);
+ });
+ } else {
+ console.log("MYPAGE KEYEVT: Skip events::>" + event.keyCode);
+ }
+ } else if (_state.menu.stage == "popup_message_card") {
+ if (event.keyCode == 461) {
+ if ($('.popup>.mypage>.message').css('display') != "none") {
+ $('.popup>.mypage>.message').fadeOut(500, function() {
+ _state.menu.stage = "mypage";
+ $('.main>.mypage>.slider').animate({ top: 864, left: 0 }, 1000)
+ });
+ }
+ } else {
+ console.log("POPUP MESSAGE CARD KEYEVT: Skip events::>" + event.keyCode);
+ }
+ } else {
+ console.log("INVALID MYPAGE SUBMENU STAGE::>" + _state.menu.stage);
+ }
+ });
+ _state.menu.stage = "mypage";
+ });
+
+ $('#lst_mypagesel').on('translate.owl.carousel', function(event) {
+ // 메뉴 셀렉터 좌/우 헨들링 및 이펙트
+ let idx = 0;
+ if (typeof event.item != 'undefined') {
+ idx = event.item.index;
+ } else {
+ idx = $('.main .mypage .slider .owl-item.active.center').index();
+ }
+ console.log("MYPAGE EVT(TRANSLATED) IDX::>" + idx);
+ if ($('.main .mypage .slider .owl-item').eq(idx).children('.item').length == 1) {
+ let _mp_sm = $('.main .mypage .slider .owl-item').eq(idx).children('.item')[0].id;
+
+ if (_mp_sm == "mpsel_accomodation") {
+ // MYPAGE서브 메뉴 인덱스 갱신
+ _state.menu.main[_mmIdx].cur = 'accomodation';
+ } else if (_mp_sm == "mpsel_message") {
+ let __curMsgDspIdx = 0;
+ // MYPAGE서브 메뉴 인덱스 갱신
+ _state.menu.main[_mmIdx].cur = 'message';
+
+ // 메시지 포커싱
+ if ('message' in Object.keys(_state.menu.main[_mmIdx])) {
+ __curMsgDspIdx = _state.menu.main[_mmIdx].message.cur;
+ } else {
+ _state.menu.main[_mmIdx]['message'] = {
+ "cnt": Object.keys(_msg).length,
+ "cur": __curMsgDspIdx,
+ "prev": null,
+ }
+ }
+ $('.main>.mypage>.bg>.owl-carousel .owl-item #mp_msg_tblrec tr').removeClass('focus');
+ $('.main>.mypage>.bg>.owl-carousel .owl-item #mp_msg_tblrec tr').filter("[msgidx='" + __curMsgDspIdx + "']").addClass('focus');
+ }
+ console.log("MYPAGE EVT(TRANSLATED) MYPAGE MENU::>" + _state.menu.main[_mmIdx].cur);
+ }
+ $('.main .mypage .slider .owl-item.focus').removeClass('focus');
+ $('.main .mypage .slider .owl-item.unfocus').removeClass('unfocus');
+ $('.main .mypage .slider .owl-item').eq(idx).addClass('focus');
+ $('.main .mypage .slider .owl-item').eq(idx - 1).addClass('unfocus');
+ $('.main .mypage .slider .owl-item').eq(idx + 1).addClass('unfocus');
+ });
+ });
+
+
+ }
+
+ /**
+ * HotelTV UI[AppFull] Wrapper Function::> request tv channel function
+ */
+ function __uifxn_AppFull_TVRequestChannel() {
+ const _state = HotelTV.state;
+ const tv_mmIdx = _state.menu.main.cur;
+ const tv_ctgIdx = _state.menu.main[tv_mmIdx].cur;
+ const tv_chIdx = _state.menu.main[tv_mmIdx][tv_ctgIdx].cur;
+ const ch_info = HotelTV.profile[tv_mmIdx].channel[tv_ctgIdx][tv_chIdx];
+ let _need_to_changeTVChannel = false;
+ let _tm_diff_ms = 0;
+
+ if (_lastTm.tvchannel_changed == null) {
+ _lastTm.tvchannel_changed = new Date();
+ _need_to_changeTVChannel = true;
+ } else {
+ let _tm_cur = new Date();
+ _tm_diff_ms = Math.floor(_tm_cur.getTime() - _lastTm.tvchannel_changed.getTime());
+ //마지막 TV채널 변경 시간 갱신
+ _lastTm.tvchannel_changed = _tm_cur;
+
+ if (_tm_diff_ms > 200) {
+ _need_to_changeTVChannel = true;
+ }
+ }
+
+ if (_need_to_changeTVChannel == true) {
+ console.log(`CHANGE::TVCTG[${HotelTV.profile[tv_mmIdx].channel[tv_ctgIdx].channel_category[_state.lang]}]` +
+ ` CUR CH IDX::>${tv_chIdx} EPGID: ${ch_info.epg_id} URL::>${ch_info.url} TMDIFF::>${_tm_diff_ms}`);
+
+
+ let _uri_stream = ch_info.url.split('://@')[1];
+ let _typ_proto = ch_info.url.split('://@')[0];
+ let _uri_ip = _uri_stream.split(':')[0];
+ let _uri_port = _uri_stream.split(':')[1];
+ //console.log(`ip = ${_uri_ip} port=${_uri_port} protocol=${_typ_proto}`);
+ HotelTV.hcap.ChannelSetup("ip", { "ip": _uri_ip, "port": Number(_uri_port), "ptype": _typ_proto });
+
+
+ // {
+ // let min = Math.ceil(0);
+ // let max = Math.floor(16);
+ // let _major = Math.floor(Math.random() * (max - min + 1)) + min;
+ // console.log("Major=5 minor=" + _major);
+ // HotelTV.hcap.ChannelSetup("rf_analog_ntsc", { "major": _major, "minor": 0 });
+ // }
+ } else {
+ console.log(`SKIPPED::TVCTG[${HotelTV.profile[tv_mmIdx].channel[tv_ctgIdx].channel_category[_state.lang]}]` +
+ ` CUR CH IDX::>${tv_chIdx} EPGID: ${ch_info.epg_id} URL::>${ch_info.url} TMDIFF::>${_tm_diff_ms}`);
+ }
+ }
+
+ /**
+ * HotelTV UI[AppFull] Wrapper Function::> update tv channel list within selected tv category
+ * @param {string} _action parameter
+ */
+ function __uifxn_AppFull_TVUpdateChList(_action) {
+ const _state = HotelTV.state;
+ const tv_mmIdx = _state.menu.main.cur;
+ const tv_ctgIdx = _state.menu.main[tv_mmIdx].cur;
+ const tv_chIdx = _state.menu.main[tv_mmIdx][tv_ctgIdx].cur; //프로파일 상의 채널 인덱스(문자열)
+ let tv_chElIdx = Number(tv_chIdx) - 1; //엘리멘트 인덱스(0베이스)
+ const ch_info = HotelTV.profile[tv_mmIdx].channel[tv_ctgIdx][tv_chIdx];
+
+ //CENTER로 마킹된 엘리멘트 가져오기
+ let _hndlOwlCtrEl = $('.main .tv .bg .owl-carousel .owl-stage-outer .owl-item.center');
+ if (_hndlOwlCtrEl.length == 1) {
+ //현재 ACTIVATED(CENTER)된 OWL로부터 tvctgfrm_xxx과 같은 아이디 가져오기
+ let _targetChListId = $(_hndlOwlCtrEl.find(".item")).attr('id');
+ //_targetChListId는 tvctgfrm_xxxx와 같은 형식임
+ let _el_target = $('#' + _targetChListId + ' .tvctg_chlist');
+ if (_action == "on_load") {
+ if (_el_target.find('.focused').length == 0) {
+ _el_target.stop().animate({ scrollTop: ((tv_chElIdx - 2) * 120).toString() }, 500, function() {
+ __uifxn_AppFull_TVRequestChannel();
+ });
+ _el_target.each(function(index, item) {
+ $($(item).children()[tv_chElIdx]).addClass("focused");
+ });
+ _state.menu.stage = "tvCtgShow";
+ console.log("1st time ....");
+ }
+ } else if (_action == "ch_up") {
+ if ((tv_chElIdx >= 2) && (tv_chElIdx < (Number(_state.menu.main[tv_mmIdx][tv_ctgIdx].cnt) - 3))) {
+ _el_target.stop().animate({ scrollTop: ((tv_chElIdx - 2) * 120).toString() }, 500, function() {
+ __uifxn_AppFull_TVRequestChannel();
+ });
+ } else {
+ __uifxn_AppFull_TVRequestChannel();
+ }
+
+ _el_target.each(function(index, item) {
+ $($(item).children()[tv_chElIdx + 1]).removeClass("focused");
+ $($(item).children()[tv_chElIdx]).addClass("focused");
+ });
+ } else if (_action == "ch_down") {
+ if ((tv_chElIdx > 2) && (tv_chElIdx < (Number(_state.menu.main[tv_mmIdx][tv_ctgIdx].cnt) - 2))) {
+ _el_target.stop().animate({ scrollTop: ((tv_chElIdx - 2) * 120).toString() }, 500, function() {
+ __uifxn_AppFull_TVRequestChannel();
+ });
+ } else {
+ __uifxn_AppFull_TVRequestChannel();
+ }
+ _el_target.each(function(index, item) {
+ $($(item).children()[tv_chElIdx - 1]).removeClass("focused");
+ $($(item).children()[tv_chElIdx]).addClass("focused");
+ });
+ }
+ } else {
+ console.log("ERROR::> No centered Item");
+ }
+ }
+
+ /**
+ * HotelTV UI[AppFull] Wrapper Function::> Buildup sub menu and main bg
+ */
+ function __uifxn_AppFull_Update_CtzThumbnail() {
+ let _state = HotelTV.state;
+ let _mmIdx = _state.menu.main.cur;
+ let _smIdx = _state.menu.main[_mmIdx].cur;
+ if (_state.menu.main[_mmIdx][_smIdx] && _state.menu.main[_mmIdx][_smIdx].cur) {
+ let _ctzidx = _state.menu.main[_mmIdx][_smIdx].cur;
+ let _program = HotelTV.tvguide.program;
+ let _ctzinfo = _program[_mmIdx].children[_smIdx].children;
+
+ if (_state.menu.main[_mmIdx][_smIdx].thumbimg[_ctzidx].idx < _state.menu.main[_mmIdx][_smIdx].thumbimg[_ctzidx].cnt) _state.menu.main[_mmIdx][_smIdx].thumbimg[_ctzidx].idx++;
+ else _state.menu.main[_mmIdx][_smIdx].thumbimg[_ctzidx].idx = 1;
+ let _img_ctz_thumbnail = $('.main .ctzgen .bg .owl-carousel .owl-item.active .ctz_desc_frame #ctz_thumbnail img');
+
+ _img_ctz_thumbnail.fadeOut(1000, function() {
+ _img_ctz_thumbnail.attr({
+ src: _ctzinfo[_ctzidx].thumbnails.files[_state.lang][_state.menu.main[_mmIdx][_smIdx].thumbimg[_ctzidx].idx].download
+ });
+ }).fadeIn(1000);
+ //console.log("CTZ(THUMBNAIL) UPDATED::> " + _state.menu.main[_mmIdx][_smIdx].thumbimg[_ctzidx].idx);
+ }
+ }
+
+
+ /**
+ * HotelTV UI[AppFull] Wrapper Function::> Buildup sub menu and main bg
+ */
+ function __uifxn_AppFull_BldPage_CtzGeneral() {
+ let _trTbl = HotelTV.translation;
+ let _state = HotelTV.state;
+ let _mmIdx = _state.menu.main.cur;
+ let _smIdx = _state.menu.main[_mmIdx].cur;
+ let _program = HotelTV.tvguide.program;
+ let _ctzinfo = _program[_mmIdx].children[_smIdx].children;
+
+
+ if (!(_smIdx in _state.menu.main[_mmIdx])) {
+ _state.menu.main[_mmIdx][_smIdx] = {
+ 'cnt': 0,
+ 'cur': null,
+ 'prev': null,
+ 'thumbimg': {}
+ };
+ _state.menu.main[_mmIdx][_smIdx].cnt = _ctzinfo.length;
+ }
+
+ // UI State Flag 설정
+ _state.menu.stage = "preparing_ctz_general";
+ if (_state.menu.main[_mmIdx][_smIdx].cur == null) {
+ _state.menu.main[_mmIdx][_smIdx].cur = Object.keys(_ctzinfo)[0];
+ }
+
+ // 컨텐트 매뉴 백그라운드 이미지 노드를 동적으로 구성
+ let _div_ctzgen_bglist = document.querySelector('#lst_ctzgenbg');
+ for (let _ctzidx = 1; _ctzidx <= _ctzinfo.length; _ctzidx++) {
+ let _div_ctz_item = document.createElement('div');
+ let _sz_styleOpt = null;
+
+ _div_ctz_item.className = 'item';
+ _div_ctz_item.id = _ctzinfo[_ctzidx].id;
+ _div_ctz_item.setAttribute("cgzgenid", _ctzidx);
+ _sz_styleOpt = "--bg_noplay: url(" + _ctzinfo[_ctzidx].background.file.download + "); ";
+ _sz_styleOpt += "background-repeat: no-repeat; background-position: center bottom; background-size: 100% 100%; ";
+ _div_ctz_item.setAttribute("style", _sz_styleOpt);
+
+
+ // 컨텐트 DESCRIPTION용 DIV 삽입
+ let _div_ctz_frame = document.createElement('div');
+ _div_ctz_frame.setAttribute("class", "ctz_desc_frame");
+
+ // 컨텐트 타이틀 삽입
+ let _div_ctz_title = document.createElement('div');
+ _div_ctz_title.setAttribute("id", "ctz_title");
+ _div_ctz_title.textContent = _ctzinfo[_ctzidx].title[_state.lang];
+ _div_ctz_frame.appendChild(_div_ctz_title);
+
+ // 컨텐트 썸네일 삽입
+ let _div_ctz_thumbnail = document.createElement('div');
+ _div_ctz_thumbnail.setAttribute("id", "ctz_thumbnail");
+ // if (_ctzinfo[_ctzidx].thumbnails.interval > 0) {
+ // let _ul_ctz_thumbnail = document.createElement('ul');
+ // for (_tmbidx = 1; _tmbidx <= _ctzinfo[_ctzidx].thumbnails.files[_state.lang].length; _tmbidx++) {
+ // let _ui_ctz_thumbnail = document.createElement('li');
+ // let _img_ctz_thumbnail = document.createElement('img');
+ // _img_ctz_thumbnail.src = _ctzinfo[_ctzidx].thumbnails.files[_state.lang][_tmbidx].download;
+ // _ui_ctz_thumbnail.appendChild(_img_ctz_thumbnail);
+ // _ul_ctz_thumbnail.appendChild(_ui_ctz_thumbnail);
+ // }
+ // _div_ctz_thumbnail.appendChild(_ul_ctz_thumbnail);
+ // } else {
+ // _sz_styleOpt = "background-image: url(" + _ctzinfo[_ctzidx].thumbnails.files[_state.lang][1].download + "); ";
+ // _sz_styleOpt += "background-repeat: no-repeat; background-position: left center; background-size: contain; ";
+ // _div_ctz_thumbnail.setAttribute("style", _sz_styleOpt);
+ // }
+ // _sz_styleOpt = "background-image: url(" + _ctzinfo[_ctzidx].thumbnails.files[_state.lang][1].download + "); ";
+ // _sz_styleOpt += "background-repeat: no-repeat; background-position: left center; background-size: contain; ";
+ // _div_ctz_thumbnail.setAttribute("style", _sz_styleOpt);
+ let _img_ctz_thumbnail = document.createElement('img');
+ _img_ctz_thumbnail.src = _ctzinfo[_ctzidx].thumbnails.files[_state.lang][1].download;
+ _div_ctz_thumbnail.appendChild(_img_ctz_thumbnail);
+ _div_ctz_frame.appendChild(_div_ctz_thumbnail);
+
+ // 썸네일 에니메이션 관리용 맴버 추가 및 초기화
+ _state.menu.main[_mmIdx][_smIdx].thumbimg[_ctzidx] = { "cnt": _ctzinfo[_ctzidx].thumbnails.files[_state.lang].length, "idx": 1 };
+
+ // 컨텐트 설명 삽입
+ let _div_ctz_desc = document.createElement('div');
+ _div_ctz_desc.setAttribute("id", "ctz_description");
+ _div_ctz_desc.innerHTML = "" + _ctzinfo[_ctzidx].description[_state.lang].replace(/(?:\r\n|\r|\n)/g, '
') + "
";
+ _div_ctz_frame.appendChild(_div_ctz_desc);
+
+ _div_ctz_item.appendChild(_div_ctz_frame);
+
+ // 동영상이 있는 경우, PLAY안내 버튼 노출
+ if (_ctzinfo[_ctzidx].video.enable == true && _ctzinfo[_ctzidx].video.files[_state.lang]) {
+ let _div_ctz_mvctrl = document.createElement('div');
+ _div_ctz_mvctrl.setAttribute("class", "ctz_mv_ctrl");
+ _div_ctz_mvctrl.setAttribute("video_url", _ctzinfo[_ctzidx].video.files[_state.lang].download);
+ _sz_styleOpt = '--playmsg: "' + _trTbl.ui.player.watch_movie[_state.lang] + '";';
+ _sz_styleOpt += '--stopmsg: "' + _trTbl.ui.player.stop_movie[_state.lang] + '";';
+ _div_ctz_mvctrl.setAttribute("style", _sz_styleOpt);
+ _div_ctz_item.appendChild(_div_ctz_mvctrl);
+ }
+
+ _div_ctzgen_bglist.appendChild(_div_ctz_item);
+ }
+
+ _hndl_ctzGenBg = $('#lst_ctzgenbg');
+ _hndl_ctzGenBg.owlCarousel({
+ center: false,
+ items: 1, //Number of Items on Screen what you want
+ loop: false,
+ margin: 0,
+ smartSpeed: 0,
+ lazyLoad: true,
+ mouseDrag: false,
+ touchDrag: false,
+ pullDrag: false,
+ freeDrag: false,
+ startPosition: Number(_state.menu.main[_mmIdx][_smIdx].cur) - 1,
+ });
+
+ //서브 페이지->콘텐트 페이지 화면 전환
+ $('.main .ctzgen').show(function() {
+ $('.main .ctzgen .bg').show(function() {
+ $('.main').animate({ top: -2160, left: 0 }, 1000, function() {
+ $('.main .sub').fadeOut(600);
+ //$('#lst_ctzgenbg').trigger('translate.owl.carousel', [0]);
+ $('#lst_ctzgenbg').trigger('translate.owl.carousel', [0, 500, true]);
+ _state.menu.stage = "ctzgen";
+ });
+ });
+ });
+
+
+ $('#lst_ctzgenbg').on('change.owl.carousel', function(event) {
+ // Update HotelTV sub menu status
+ let _state = HotelTV.state;
+ let _mmIdx = _state.menu.main.cur;
+ let _smIdx = _state.menu.main[_mmIdx].cur;
+ let _program = HotelTV.tvguide.program;
+ let _ctzinfo = _program[_mmIdx].children[_smIdx].children;
+ _state.menu.main[_mmIdx][_smIdx].prev = Object.keys(_ctzinfo)[event.page.index];
+ });
+
+ $('#lst_ctzgenbg').on('changed.owl.carousel', function(event) {
+ // Update HotelTV sub menu status
+ let _state = HotelTV.state;
+ let _mmIdx = _state.menu.main.cur;
+ let _smIdx = _state.menu.main[_mmIdx].cur;
+ let _program = HotelTV.tvguide.program;
+ let _ctzinfo = _program[_mmIdx].children[_smIdx].children;
+ _state.menu.main[_mmIdx][_smIdx].cur = Object.keys(_ctzinfo)[event.page.index];
+
+ if (_ctzinfo[_state.menu.main[_mmIdx][_smIdx].cur].thumbnails.interval > 0) {
+ if (_hndl_tmrCtzThumbAni != null) {
+ clearInterval(_hndl_tmrCtzThumbAni);
+ _hndl_tmrCtzThumbAni = null;
+ console.log("TMR(CTZ ANI)::>Destoried...");
+ }
+ _hndl_tmrCtzThumbAni = setInterval(__uifxn_AppFull_Update_CtzThumbnail, Number(_ctzinfo[_state.menu.main[_mmIdx][_smIdx].cur].thumbnails.interval) * 1000);
+ console.log("TMR::>Created...");
+ } else {
+ if (_hndl_tmrCtzThumbAni != null) {
+ clearInterval(_hndl_tmrCtzThumbAni);
+ _hndl_tmrCtzThumbAni = null;
+ console.log("TMR(CTZ ANI)::>Destoried...");
+ }
+ }
+ console.log("CTZ(GEN) IDX::>" + _state.menu.main[_mmIdx][_smIdx].cur);
+ });
+
+ $('#lst_ctzgenbg').on('translate.owl.carousel', function(event) {
+ // 메뉴 셀렉터 좌/우 헨들링 및 이펙트
+ let idx = 0;
+ if (typeof event.item != 'undefined') {
+ idx = event.item.index;
+ } else {
+ idx = $('.main .ctzgen .bg .owl-item.active').index();
+ }
+
+ if ($('.main .ctzgen .bg .owl-item').eq(idx).hasClass('movieplay') == true) {
+ if ($('.owl-theme .owl-nav.disabled+.owl-dots').css('display') != 'none') {
+ $('.owl-theme .owl-nav.disabled+.owl-dots').fadeOut(500);
+ }
+ } else {
+ if ($('.owl-theme .owl-nav.disabled+.owl-dots').css('display') == 'none') {
+ $('.owl-theme .owl-nav.disabled+.owl-dots').fadeIn(500);
+ }
+ }
+ });
+ }
+
+
+ /**
+ * HotelTV UI[AppFull] Wrapper Function::> Buildup sub menu and main bg
+ */
+ function __uifxn_AppFull_BldPage_SubGeneral() {
+ let _trTbl = HotelTV.translation;
+ let _state = HotelTV.state;
+ let _mmIdx = _state.menu.main.cur;
+ let _program = HotelTV.tvguide.program;
+ let _sminfo = _program[_mmIdx].children;
+
+ if (!(_mmIdx in _state.menu.main)) {
+ _state.menu.main[_mmIdx] = {
+ 'cnt': 0,
+ 'cur': null,
+ 'prev': null,
+ };
+ _state.menu.main[_mmIdx].cnt = _sminfo.length;
+ }
+
+ // 초기 메인 메뉴 KEY설정
+ _state.menu.stage = "preparing_sub";
+ if (_state.menu.main[_mmIdx].cur == null) {
+ _state.menu.main[_mmIdx].cur = Object.keys(_sminfo)[0];
+ }
+
+ // 서브 메뉴 셀렉터 노드를 동적으로 구성
+ let _div_sm_slist = document.querySelector('#lst_smsel');
+ for (let _idx = 1; _idx <= _sminfo.length; _idx++) {
+ let _div_sm_item = document.createElement('div');
+ _div_sm_item.className = 'item';
+ _div_sm_item.id = _sminfo[_idx].id;
+ _div_sm_item.setAttribute("smid", _idx);
+
+ // Append Sub elements::title
+ let _sm_item_title = document.createElement('div');
+ _sm_item_title.setAttribute("id", "sm_item_title");
+ _sm_item_title.textContent = _sminfo[_idx].title[_state.lang];
+
+ // Append Sub elements::icon
+ let _sm_item_icon = document.createElement('div');
+ _sm_item_icon.setAttribute("id", "sm_item_icon");
+ let _sz_styleOpt = "--icon_unfocus: url(" + _sminfo[_idx].unfocusIcon.file.download + "); ";
+ _sz_styleOpt += "--icon_focus: url(" + _sminfo[_idx].focusIcon.file.download + "); ";
+ //_sz_styleOpt += "background-repeat: no-repeat; background-position: center bottom; background-size: 100% 100%; ";
+ _sz_styleOpt += "background-repeat: no-repeat; background-position: center bottom;";
+ _sm_item_icon.setAttribute("style", _sz_styleOpt);
+
+ _div_sm_item.appendChild(_sm_item_icon);
+ _div_sm_item.appendChild(_sm_item_title);
+
+ _div_sm_slist.appendChild(_div_sm_item);
+ }
+
+ // 서브 메뉴 백그라운드 이미지 노드를 동적으로 구성
+ let _div_sm_bglist = document.querySelector('#lst_smbg');
+ for (let _idx = 1; _idx <= _sminfo.length; _idx++) {
+ let _div_sm_item = document.createElement('div');
+ let _sz_styleOpt = null;
+
+ _div_sm_item.className = 'item';
+ _div_sm_item.id = _sminfo[_idx].id;
+ _div_sm_item.setAttribute("smid", _idx);
+ _sz_styleOpt = "background-image: url(" + _sminfo[_idx].background.file.download + "); ";
+ _sz_styleOpt += "background-repeat: no-repeat; background-position: center center; background-size: 100% 100%; ";
+ _div_sm_item.setAttribute("style", _sz_styleOpt);
+
+ //해당 서버메뉴가 하위에 콘텐트를 가지고 있는 경우
+ if (_sminfo[_idx].type.toLowerCase() == 'menu') {
+ // 컨텐트 썸네일 베경 화면에 삽입
+ let _div_sm_ctz_frame = document.createElement('div');
+ _div_sm_ctz_frame.setAttribute("class", "bg_ctz_thumb_frame");
+
+ // 컨텐트 썸네일 타이틀(신규 콘텐트)문구 삽입
+ let _div_sm_ctz_title = document.createElement('div');
+ _div_sm_ctz_title.setAttribute("id", "bg_ctz_thumb_title");
+ _div_sm_ctz_title.textContent = _trTbl.ui.misc.title.new_ctz[_state.lang];
+ _div_sm_ctz_frame.appendChild(_div_sm_ctz_title);
+
+
+ let _ctz_info = _sminfo[_idx].children;
+ for (let _ctzidx = 1; _ctzidx <= _sminfo[_idx].children.length; _ctzidx++) {
+ if (Number(_ctzidx) < 4) {
+ let _div_sm_ctz_item = document.createElement('div');
+ _div_sm_ctz_item.setAttribute("id", "bg_ctz_thumb_item");
+ // 해당 서브메뉴 아이탬의 하위 콘텐트들의 첫 썸네일 이미지
+ _sz_styleOpt = "background-image: url(" + _ctz_info[_ctzidx].thumbnails.files[_state.lang][1].download + "); ";
+ _sz_styleOpt += "background-repeat: no-repeat; background-position: center center; background-size: 100% 100%; ";
+ _sz_styleOpt += "background-color: rgba(0,0,0,0.4)";
+ _div_sm_ctz_item.setAttribute("style", _sz_styleOpt);
+ _div_sm_ctz_item.textContent = _ctz_info[_ctzidx].title[_state.lang];
+ _div_sm_ctz_frame.appendChild(_div_sm_ctz_item);
+ }
+ }
+
+ // 추가 콘텐트 갯수 표시
+ if (_ctz_info.length > 3) {
+ let _div_sm_ctz_notice = document.createElement('div');
+ _div_sm_ctz_notice.setAttribute("id", "bg_ctz_thumb_morenotice");
+ let _remain_ctz_cnt = _ctz_info.length - 3;
+ let _str_remain_ctz_cnt = _trTbl.ui.submenu.info.remain_ctz_cnt;
+ _div_sm_ctz_notice.textContent = _str_remain_ctz_cnt[_state.lang].replace('__CTZCNT', _remain_ctz_cnt);
+ _div_sm_ctz_frame.appendChild(_div_sm_ctz_notice);
+ }
+ _div_sm_item.appendChild(_div_sm_ctz_frame);
+
+ //Set Attribute
+ _div_sm_item.setAttribute("ctzUse", true);
+ } else {
+ _div_sm_item.setAttribute("ctzUse", false);
+ //contents_use가 1이 아닌경우, 이에 대한 페이지 활용 아이디어 필요
+ }
+ _div_sm_bglist.appendChild(_div_sm_item);
+ }
+
+ _hndl_smBg = $('#lst_smbg');
+ _hndl_smBg.owlCarousel({
+ center: true,
+ items: 1, //Number of Items on Screen what you want
+ loop: true,
+ margin: 0,
+ smartSpeed: 1000,
+ lazyLoad: true,
+ mouseDrag: false,
+ touchDrag: false,
+ pullDrag: false,
+ freeDrag: false,
+ startPosition: (Number(_state.menu.main[_mmIdx].cur) - 1),
+ });
+ $('.main .sub').show(function() {
+ $('.main .mm').fadeOut(800);
+ });
+
+ _hndl_smSel = $('#lst_smsel');
+ _hndl_smSel.owlCarousel({
+ center: true,
+ items: 3, //Number of Items on Screen what you want
+ loop: true,
+ margin: 0,
+ smartSpeed: 0,
+ autoWidth: false,
+ mouseDrag: false,
+ touchDrag: false,
+ pullDrag: false,
+ freeDrag: false,
+ startPosition: (Number(_state.menu.main[_mmIdx].cur) - 1),
+ });
+
+ //메인 페이지->서브 페이지 화면 전환
+ $('.main .sub .slider').show(function() {
+ $('.main').animate({ top: -1080, left: 0 }, 1000, function() {
+
+ $('.main .sub .slider .owl-item').addClass('unfocus');
+ $('#lst_smsel').trigger("to.owl.carousel", [(Number(_state.menu.main[_mmIdx].cur) - 1), 10, true]);
+ $('#lst_smsel').trigger('translate.owl.carousel', [0, 500, true]);
+
+ $(document.activeElement).keydown(function(event) { //attach event listener
+ if (_state.menu.stage == "sub") {
+ if (event.keyCode == 37) {
+ $('#lst_smsel').trigger('prev.owl', 700);
+ } else if (event.keyCode == 39) {
+ $('#lst_smsel').trigger('next.owl', 700);
+ } else if (event.keyCode == 13) {
+ // 콘텐트 리스트 화면 빌드 및 화면 전환
+ let _program = HotelTV.tvguide.program;
+ let _mmIdx = _state.menu.main.cur;
+ if (_program[_mmIdx].type.toLowerCase() == "normal") {
+ if (_program[_mmIdx].style.toLowerCase() == "none") {
+ console.log("Invalid options");
+ } else if (_program[_mmIdx].style.toLowerCase() == "content") {
+ console.log("Invalid options");
+ } else if (_program[_mmIdx].style.toLowerCase() == "submenu") {
+ __uifxn_AppFull_BldPage_CtzGeneral();
+ }
+ }
+ } else if (event.keyCode == 461) {
+ // 컨텐트 폼의 썸네일 에니메이션용 타이머 제거
+ if (_hndl_tmrCtzThumbAni != null) {
+ clearInterval(_hndl_tmrCtzThumbAni);
+ _hndl_tmrCtzThumbAni = null;
+ console.log("TMR(CTZ ANI)::>Destoried...");
+ }
+
+ // 메인 메뉴로 귀환
+ $(document.activeElement).off('keydown');
+ $('.main .mm').show(function() {
+ $('#lst_mmsel').trigger('translate.owl.carousel', [0]);
+ });
+ $('.main').animate({ top: 0, left: 0 }, 1000, () => {
+ $('#lst_smsel').off('refresh.owl.carousel');
+ $('#lst_smsel').off('change.owl.carousel');
+ $('#lst_smsel').off('changed.owl.carousel');
+ $('#lst_smsel').off('translate.owl.carousel');
+
+ $('#lst_smbg').owlCarousel('destroy');
+ $('#lst_smsel').owlCarousel('destroy');
+
+ $('.main .sub .slider #lst_smsel div').remove();
+ $('.main .sub .bg #lst_smbg div').remove();
+ $('.main .sub').hide();
+ _hndl_smSel = null;
+ _hndl_smBg = null;
+ _state.menu.stage = "main"
+ setTimeout(function() {
+ __uifxn_AppFull_ShowMMHotKeyBtn(true);
+ }, 500);
+ });
+ }
+ } else if (_state.menu.stage == "ctzgen") {
+ if (event.keyCode == 37) {
+ $('#lst_ctzgenbg').trigger('prev.owl', 700);
+ } else if (event.keyCode == 39) {
+ $('#lst_ctzgenbg').trigger('next.owl', 700);
+ } else if (event.keyCode == 461) {
+ $('.main .sub').show();
+ $('.main').animate({ top: -1080, left: 0 }, 1000, () => {
+ $('.main .ctzgen').hide();
+ _state.media.playing = false;
+ HotelTV.hcap.MediaStop(null, null);
+
+ $('#lst_ctzgenbg').off('refresh.owl.carousel');
+ $('#lst_ctzgenbg').off('change.owl.carousel');
+ $('#lst_ctzgenbg').off('changed.owl.carousel');
+ $('#lst_ctzgenbg').off('translate.owl.carousel');
+ $('#lst_ctzgenbg').owlCarousel('destroy');
+ $('.main .ctzgen .bg #lst_ctzgenbg div').remove();
+ _hndl_ctzGenBg = null;
+ _state.menu.stage = "sub";
+ $('#lst_smsel').trigger('translate.owl.carousel', [0]);
+ });
+ } else if (event.keyCode == 415) {
+ if ($('.main .ctzgen .bg .owl-carousel .owl-item.active .ctz_mv_ctrl').length == 1) {
+ let uri_video = $($('.main .ctzgen .bg .owl-carousel .owl-item.active .ctz_mv_ctrl')[0]).attr('video_url');
+ if (uri_video != null) {
+ HotelTV.hcap.MediaPlay(
+ HotelTV.api.GetBaseUrl() + uri_video,
+ "",
+ "video/mp4",
+ 1,
+ () => {
+ console.log("STARTUP Done CB.");
+ },
+ () => {
+ console.log("STARTUP Fail CB.");
+ }
+ );
+ }
+ }
+ } else if (event.keyCode == 413) {
+ if (_state.media.playing == true) {
+ _state.media.playing = false;
+ HotelTV.hcap.MediaStop(
+ function() {
+ $('.main .ctzgen .bg .owl-carousel .owl-stage-outer .owl-stage .owl-item').removeClass('movieplay');
+ $('.owl-theme .owl-nav.disabled+.owl-dots').fadeIn(1000);
+ },
+ function() {
+ $('.main .ctzgen .bg .owl-carousel .owl-stage-outer .owl-stage .owl-item').removeClass('movieplay');
+ $('.owl-theme .owl-nav.disabled+.owl-dots').fadeIn(1000);
+ });
+ }
+ } else {
+ console.log('CTZ MENU: KEY::> ' + event.keyCode);
+ }
+ } else {
+ console.log("SUBMENU KEYEVT: Skip events");
+ }
+ });
+ _state.menu.stage = "sub";
+ });
+ });
+
+ $('#lst_smsel').on('change.owl.carousel', function(event) {
+ // Update HotelTV sub menu status
+ let _state = HotelTV.state;
+ let _mmIdx = _state.menu.main.cur;
+ let _sminfo = HotelTV.tvguide.program[_mmIdx].children;
+ _state.menu.main[_mmIdx].prev = Object.keys(_sminfo)[event.page.index];
+ });
+
+ $('#lst_smsel').on('changed.owl.carousel', function(event) {
+ // Update HotelTV sub menu status
+ let _state = HotelTV.state;
+ let _mmIdx = _state.menu.main.cur;
+ let _sminfo = HotelTV.tvguide.program[_mmIdx].children;
+ _state.menu.main[_mmIdx].cur = Object.keys(_sminfo)[event.page.index];
+ //console.log("SUB IDX::>" + _state.menu.main[_mmIdx].cur);
+ __uifxn_AppFull_OnKeyDnEvt_SmSel(event);
+ });
+
+ $('#lst_smsel').on('translate.owl.carousel', function(event) {
+ // 메뉴 셀렉터 좌/우 헨들링 및 이펙트
+ let idx = 0;
+ if (typeof event.item != 'undefined') {
+ idx = event.item.index;
+ } else {
+ idx = $('.main .sub .slider .owl-item.active.center').index();
+ }
+ console.log("SUB IDX4::>" + idx);
+ $('.main .sub .slider .owl-item.focus').addClass('unfocus');
+ $('.main .sub .slider .owl-item.focus').removeClass('focus');
+ $('.main .sub .slider .owl-item').eq(idx).addClass('focus');
+ $('.main .sub .slider .owl-item').eq(idx).removeClass('unfocus');
+ });
+ }
+
+
+ /**
+ * HotelTV UI[AppFull] Wrapper Function::> Buildup sub menu and main bg
+ */
+ function __uifxn_AppFull_BldPage_SubTV() {
+ let _state = HotelTV.state;
+ let _mmIdx = _state.menu.main.cur;
+ let _tvCtgInfo = HotelTV.profile[_mmIdx].channel;
+ let _tvCtgcnt = 0;
+
+ _tvCtgcnt = Object.keys(_tvCtgInfo).length;
+ if (!(_mmIdx in _state.menu.main)) {
+ _state.menu.main[_mmIdx] = {
+ 'cnt': 0,
+ 'cur': null,
+ 'prev': null,
+ };
+ _state.menu.main[_mmIdx].cnt = _tvCtgcnt;
+ }
+
+ // 초기 메인 메뉴 KEY설정
+ _state.menu.stage = "preparing_tv";
+ if (_state.menu.main[_mmIdx].cur == null) {
+ _state.menu.main[_mmIdx].cur = Object.keys(_tvCtgInfo)[0];
+
+ for (let _tvCtg_item in _tvCtgInfo) {
+ _state.menu.main[_mmIdx][_tvCtg_item] = {
+ 'cnt': 0,
+ 'cur': null,
+ 'prev': null,
+ };
+ _state.menu.main[_mmIdx][_tvCtg_item].cnt = Object.keys(_tvCtgInfo[_tvCtg_item]).length - 1;
+ _state.menu.main[_mmIdx][_tvCtg_item].cur = Object.keys(_tvCtgInfo[_tvCtg_item])[0];
+ }
+ }
+
+ // TV 메뉴 카테고리 노드를 동적으로 구성
+ let _div_tvCgh_bglist = document.querySelector('#lst_tvCtgbg');
+ for (let _tvCtg_item in _tvCtgInfo) {
+ let _div_tvCtg_frame = document.createElement('div');
+ let _sz_styleOpt = null;
+
+ _div_tvCtg_frame.className = 'item';
+ _div_tvCtg_frame.id = 'tvctgfrm_' + _tvCtgInfo[_tvCtg_item].channel_category['en'].replace(/\s/g, '').toLowerCase();
+ _div_tvCtg_frame.setAttribute("tvctgid", _tvCtg_item);
+
+
+
+
+ // TV 카테고리 타이틀
+ let _div_tvCtg_title = document.createElement('div');
+ _div_tvCtg_title.setAttribute("id", "tvctg_title");
+ _div_tvCtg_title.textContent = _tvCtgInfo[_tvCtg_item].channel_category[_state.lang];
+ _div_tvCtg_frame.appendChild(_div_tvCtg_title);
+
+
+ // ADD Upper Arrow
+ let _div_tvCtg_arUp = document.createElement('div');
+ _div_tvCtg_arUp.setAttribute("id", "tvctg_arrow_up");
+ _div_tvCtg_frame.appendChild(_div_tvCtg_arUp);
+
+ // TV CHANNEL LIST LIST UNDER Given TV CATEGORY
+ let _div_tv_chlist = document.createElement('div');
+ _div_tv_chlist.setAttribute("class", "tvctg_chlist");
+
+
+
+ for (let _tvCh_item in _tvCtgInfo[_tvCtg_item]) {
+ if (_tvCh_item != 'channel_category') {
+ let _div_tv_chframe = document.createElement('div');
+ _div_tv_chframe.setAttribute("class", "tvch_item_frame");
+ _div_tv_chframe.setAttribute("idx", _tvCh_item);
+
+
+ let _div_tv_chepg = document.createElement('div');
+ _div_tv_chepg.setAttribute("class", "tvch_epg");
+
+ let _span_tv_chtitle = document.createElement('span');
+ _span_tv_chtitle.setAttribute("id", "tvch_epg_title");
+ _span_tv_chtitle.textContent = _tvCtgInfo[_tvCtg_item][_tvCh_item].title[_state.lang];
+ _span_tv_chtitle.setAttribute("ch_num", "CH:" + _tvCtgInfo[_tvCtg_item][_tvCh_item].delivery_no + "]");
+ _div_tv_chepg.appendChild(_span_tv_chtitle);
+
+ let _span_tv_chepginfo = document.createElement('span');
+ _span_tv_chepginfo.setAttribute("id", "tvch_epg_info");
+ _span_tv_chepginfo.setAttribute("epg_id", _tvCtgInfo[_tvCtg_item][_tvCh_item].epg_id);
+ let _egp_prog_inf = __uifxn_AppFull_GetEpgInfoById(_tvCtgInfo[_tvCtg_item][_tvCh_item].epg_id);
+ if (_egp_prog_inf != null) {
+ _span_tv_chepginfo.textContent = _egp_prog_inf.name;
+ }
+ _div_tv_chepg.appendChild(_span_tv_chepginfo);
+
+
+ _div_tv_chframe.appendChild(_div_tv_chepg);
+
+
+
+ let _div_tv_chlogo = document.createElement('div');
+ _div_tv_chlogo.setAttribute("id", "tvch_logo");
+ _sz_styleOpt = "background-image: url(" + _tvCtgInfo[_tvCtg_item][_tvCh_item].logo.full_path + "); ";
+ _sz_styleOpt += "background-repeat: no-repeat; background-position: center center; background-size: 100%; ";
+ _div_tv_chlogo.setAttribute("style", _sz_styleOpt);
+ _div_tv_chframe.appendChild(_div_tv_chlogo);
+
+
+ _div_tv_chlist.appendChild(_div_tv_chframe);
+ }
+ }
+ _div_tvCtg_frame.appendChild(_div_tv_chlist);
+
+ // ADD Down Arrow
+ let _div_tvCtg_arDn = document.createElement('div');
+ _div_tvCtg_arDn.setAttribute("id", "tvctg_arrow_down");
+ _div_tvCtg_frame.appendChild(_div_tvCtg_arDn);
+
+ //TV 카테고리 프레임 엘리멘트에 Child엘레멘트 추가
+ _div_tvCgh_bglist.appendChild(_div_tvCtg_frame);
+ }
+
+ _hndl_tvCtg = $('#lst_tvCtgbg');
+
+ //owlCarousel을 초기화 하기 전에 등록해야할 callback 함수들
+ //initialized.owl.carousel같은 이벤트는 생성하기 전에 등록해야함.
+ //이벤트 발생 순서는 대략 아래와 같음.
+ //[1]change
+ //[2]changed
+ //[3]prepared
+ //[4]initialized
+ //[5]refresh
+ //[6]translate
+
+ _hndl_tvCtg.owlCarousel({
+ center: true,
+ items: 1, //Number of Items on Screen what you want
+ loop: true,
+ margin: 0,
+ nav: true,
+ dots: false,
+ smartSpeed: 100,
+ lazyLoad: true,
+ mouseDrag: false,
+ touchDrag: false,
+ pullDrag: false,
+ freeDrag: false,
+ startPosition: (Number(_state.menu.main[_mmIdx].cur) - 1),
+ });
+ $('.main .tv .bg').show(function() {
+ $('.main .mm').fadeOut(1000);
+ $('.main').animate({ top: -1080, left: 0 }, 1000, function() {
+ // Create Timer handle for channel guide ui show/hide
+ if (_hndl_tmrTvChnMngr == null) {
+ _hndl_tmrTvChnMngr = setInterval(__uifxn_AppFull_TVChMngrUi, 1000);
+ console.log("TMR::>Created...");
+ }
+
+ $('#lst_tvCtgbg').trigger('translated.owl.carousel', [0]);
+
+ $(document.activeElement).keydown(function(event) { //attach event listener
+ if (_state.menu.stage == "tvCtgShow") {
+ if (event.keyCode == 37) {
+ $('#lst_tvCtgbg').trigger('prev.owl', [1000])
+ } else if (event.keyCode == 39) {
+ $('#lst_tvCtgbg').trigger('next.owl', [1000])
+ } else if (event.keyCode == 38 || event.keyCode == 427) {
+ // 채널 리스트 아이탬 이동(UP)
+ let _mmIdx = _state.menu.main.cur;
+ let _curChCtg = _state.menu.main[_mmIdx].cur;
+ let _curChIdx = Number(_state.menu.main[_mmIdx][_curChCtg].cur);
+ if ((_curChIdx - 1) >= 1) {
+ _curChIdx -= 1;
+ _state.menu.main[_mmIdx][_curChCtg].cur = _curChIdx.toString();
+ console.log(`TVCTG[${HotelTV.profile[_mmIdx].channel[_curChCtg].channel_category[_state.lang]}] CUR CH::>${_state.menu.main[_mmIdx][_curChCtg].cur}`);
+
+ __uifxn_AppFull_TVUpdateChList("ch_up");
+ }
+ } else if (event.keyCode == 40 || event.keyCode == 428) {
+ // 채널 리스트 아이탬 이동(DOWN)
+ let _mmIdx = _state.menu.main.cur;
+ let _curChCtg = _state.menu.main[_mmIdx].cur;
+ let _curChIdx = Number(_state.menu.main[_mmIdx][_curChCtg].cur);
+ if ((_curChIdx + 1) <= Number(_state.menu.main[_mmIdx][_curChCtg].cnt)) {
+ _curChIdx += 1;
+ _state.menu.main[_mmIdx][_curChCtg].cur = _curChIdx.toString();
+ console.log(`TVCTG[${HotelTV.profile[_mmIdx].channel[_curChCtg].channel_category[_state.lang]}] CUR CH::>${_state.menu.main[_mmIdx][_curChCtg].cur}`);
+
+ __uifxn_AppFull_TVUpdateChList("ch_down");
+ }
+ } else if (event.keyCode == 13) {
+ // TV채널 플레이
+
+ } else if (event.keyCode == 461) {
+ // 현재 재생중인 TV채널 종료
+ HotelTV.hcap.ChannelShutDown();
+
+ if (_hndl_tmrTvChnMngr != null) {
+ clearInterval(_hndl_tmrTvChnMngr);
+ _hndl_tmrTvChnMngr = null;
+ console.log("TMR::>Destoried...");
+ }
+
+ // 메인 메뉴로 귀환
+ $(document.activeElement).off('keydown');
+ $('.main .mm').show(function() {
+ $('#lst_mmsel').trigger('refresh.owl.carousel', [0]);
+ });
+
+ $('.main').animate({ top: 0, left: 0 }, 1000, () => {
+ $('#lst_tvCtgbg').off('refresh.owl.carousel');
+ $('#lst_tvCtgbg').off('change.owl.carousel');
+ $('#lst_tvCtgbg').off('changed.owl.carousel');
+ $('#lst_tvCtgbg').off('translated.owl.carousel');
+
+ $('#lst_tvCtgbg').owlCarousel('destroy');
+
+ $('.main .tv .bg #lst_tvCtgbg div').remove();
+ _hndl_tvCtg = null;
+ _state.menu.stage = "main";
+
+ setTimeout(function() {
+ __uifxn_AppFull_ShowMMHotKeyBtn(true);
+ }, 500);
+ });
+ }
+ } else if (_state.menu.stage == "tvCtgHide") {
+ if (event.keyCode == 427) {
+ // 채널 리스트 아이탬 이동(UP)
+ let _mmIdx = _state.menu.main.cur;
+ let _curChCtg = _state.menu.main[_mmIdx].cur;
+ let _curChIdx = Number(_state.menu.main[_mmIdx][_curChCtg].cur);
+ if ((_curChIdx - 1) >= 1) {
+ _curChIdx -= 1;
+ _state.menu.main[_mmIdx][_curChCtg].cur = _curChIdx.toString();
+ console.log(`TVCTG[${HotelTV.profile[_mmIdx].channel[_curChCtg].channel_category[_state.lang]}] CUR CH::>${_state.menu.main[_mmIdx][_curChCtg].cur}`);
+
+ __uifxn_AppFull_TVUpdateChList("ch_up");
+ }
+ } else if (event.keyCode == 428) {
+ // 채널 리스트 아이탬 이동(DOWN)
+ let _mmIdx = _state.menu.main.cur;
+ let _curChCtg = _state.menu.main[_mmIdx].cur;
+ let _curChIdx = Number(_state.menu.main[_mmIdx][_curChCtg].cur);
+ if ((_curChIdx + 1) <= Number(_state.menu.main[_mmIdx][_curChCtg].cnt)) {
+ _curChIdx += 1;
+ _state.menu.main[_mmIdx][_curChCtg].cur = _curChIdx.toString();
+ console.log(`TVCTG[${HotelTV.profile[_mmIdx].channel[_curChCtg].channel_category[_state.lang]}] CUR CH::>${_state.menu.main[_mmIdx][_curChCtg].cur}`);
+
+ __uifxn_AppFull_TVUpdateChList("ch_down");
+ }
+ } else if (event.keyCode == 461) {
+ // 현재 재생중인 TV채널 종료
+ HotelTV.hcap.ChannelShutDown();
+
+ if (_hndl_tmrTvChnMngr != null) {
+ clearInterval(_hndl_tmrTvChnMngr);
+ _hndl_tmrTvChnMngr = null;
+ console.log("TMR::>Destoried...");
+ }
+
+ // 메인 메뉴로 귀환
+ $(document.activeElement).off('keydown');
+ $('.main .mm').show(function() {
+ $('#lst_mmsel').trigger('refresh.owl.carousel', [0]);
+ });
+
+ $('.main').animate({ top: 0, left: 0 }, 1000, () => {
+ $('#lst_tvCtgbg').off('refresh.owl.carousel');
+ $('#lst_tvCtgbg').off('change.owl.carousel');
+ $('#lst_tvCtgbg').off('changed.owl.carousel');
+ $('#lst_tvCtgbg').off('translated.owl.carousel');
+
+ $('#lst_tvCtgbg').owlCarousel('destroy');
+
+ $('.main .tv .bg #lst_tvCtgbg div').remove();
+ _hndl_tvCtg = null;
+ _state.menu.stage = "main";
+
+ setTimeout(function() {
+ __uifxn_AppFull_ShowMMHotKeyBtn(true);
+ }, 500);
+ });
+ } else {
+ console.log("event.keyCode::>" + event.keyCode);
+ }
+ } else {
+ console.log("TVMENU KEYEVT: Skip events::> Invalid menu stage:" + _state.menu.stage);
+ }
+ });
+ });
+ });
+
+ $('#lst_tvCtgbg').on('translated.owl.carousel', function(event) {
+ __uifxn_AppFull_TVUpdateChList("on_load");
+ });
+
+
+ $('#lst_tvCtgbg').on('changed.owl.carousel', function(event) {
+ // Update HotelTV sub menu status
+ let _state = HotelTV.state;
+ let _mmIdx = _state.menu.main.cur;
+ let _hndlOwlEl = $('.main .tv .bg .owl-carousel .owl-stage-outer .owl-item');
+ let _acvatedEl = null;
+ let _curChListEl = null;
+ let _curChCtg = null;
+ let _bHasValidData = false;
+
+ if (_hndlOwlEl) {
+ _acvatedEl = $(_hndlOwlEl.children()[event.item.index]);
+ if (_acvatedEl) {
+ _curChListEl = _acvatedEl.find(".tvctg_chlist");
+ if (_curChListEl) {
+ _curChCtg = _acvatedEl.attr('tvctgid');
+ _bHasValidData = true;
+ }
+ }
+ }
+ if (_bHasValidData != true) {
+ return;
+ }
+ // 현재 채널 카테고리 인덱스 갱신
+ _state.menu.main[_mmIdx].prev = _state.menu.main[_mmIdx].cur;
+ _state.menu.main[_mmIdx].cur = _curChCtg;
+ console.log("CHANGED TV CATEGORY::> CURRENT TV CTG IDX::> " + _curChCtg);
+
+ __uifxn_AppFull_TVRequestChannel();
+ });
+ }
+
+ /**
+ * HotelTV UI[AppFull] Wrapper Function::> Bottom Guide Bar UI mngr
+ */
+ function __uifxn_AppFull_GuideBarUiMngr() {
+ let _state = HotelTV.state;
+ let _newsInfo = HotelTV.news;
+ let _trTbl = HotelTV.translation;
+
+ let _tm_diff_ms = 0;
+
+ if (_lastTm.keyevt == null) {
+ _lastTm.keyevt = new Date();
+ return;
+ }
+
+ let _tm_cur = new Date();
+ _tm_diff_ms = Math.floor(_tm_cur.getTime() - _lastTm.keyevt.getTime());
+ //마지막 KEY 이벤트 수신 시간 갱신
+ //console.log(`KeyDn Event Recoreded::> ${_lastTm.keyevt} TMDiff::> ${_tm_diff_ms}`);
+
+ //
+ if (_state.menu.stage == "popup_message_card") {
+ //HIDE NEWS and USER GUIDE TIPS
+ if (_newsInfo == null || Object.keys(_newsInfo).length == 0) {
+ if ($('.news').css('display') != "none") {
+ $('.news').hide();
+ }
+ }
+
+ if ($('.guide>.tips').css('display') != "none") {
+ $('.guide>.tips').fadeOut(500);
+ }
+ return;
+ } else if (_state.menu.stage == "tvCtgHide") {
+ //HIDE NEWS and USER GUIDE TIPS
+ if (_newsInfo == null || Object.keys(_newsInfo).length == 0) {
+ if ($('.news').css('display') != "none") {
+ $('.news').hide();
+ }
+ }
+
+ if ($('.guide>.tips').css('display') != "none") {
+ $('.guide>.tips').fadeOut(500);
+ }
+ }
+
+ // TV Channel UI 지속 시간 8초
+ if (_state.media.playing == false) {
+ if (_tm_diff_ms < 8000) {
+ //SHOW USER GUIDE TIPS
+ let show_stages = ["hotkey_mm_red", "hotkey_mm_green", "hotkey_mm_yellow", "hotkey_mm_blue", "main", "sub", "ctzgen", "tvCtgShow", "mypage"];
+ let sz_msg = null;
+ if (show_stages.includes(_state.menu.stage) == true) {
+ switch (_state.menu.stage) {
+ case "hotkey_mm_red":
+ sz_msg = _trTbl.ui.guide.navi_brochure[_state.lang];
+ if ($('.guide>.tips').text() != sz_msg) {
+ $('.guide>.tips').text(sz_msg);
+ }
+ break;
+ case "hotkey_mm_green":
+ sz_msg = _trTbl.ui.guide.navi_brochure[_state.lang];
+ if ($('.guide>.tips').text() != sz_msg) {
+ $('.guide>.tips').text(sz_msg);
+ }
+ break;
+ case "hotkey_mm_yellow":
+ sz_msg = _trTbl.ui.guide.navi_brochure[_state.lang];
+ if ($('.guide>.tips').text() != sz_msg) {
+ $('.guide>.tips').text(sz_msg);
+ }
+ break;
+ case "hotkey_mm_blue":
+ sz_msg = _trTbl.ui.guide.navi_brochure[_state.lang];
+ if ($('.guide>.tips').text() != sz_msg) {
+ $('.guide>.tips').text(sz_msg);
+ }
+ break;
+ case "main":
+ //sz_msg = _trTbl.ui.guide.navi_menu[_state.lang] || "";
+ sz_msg = _trTbl.ui.guide.navi_menu[_state.lang];
+ if ($('.guide>.tips').text() != sz_msg) {
+ $('.guide>.tips').text(sz_msg);
+ }
+ break;
+ case "sub":
+ sz_msg = _trTbl.ui.guide.navi_menu[_state.lang];
+ if ($('.guide>.tips').text() != sz_msg) {
+ $('.guide>.tips').text(sz_msg);
+ }
+ break;
+ case "ctzgen":
+ sz_msg = _trTbl.ui.guide.navi_ctz[_state.lang];
+ if ($('.guide>.tips').text() != sz_msg) {
+ $('.guide>.tips').text(sz_msg);
+ }
+ break;
+ case "tvCtgShow":
+ sz_msg = _trTbl.ui.guide.navi_tvchannel[_state.lang];
+ if ($('.guide>.tips').text() != sz_msg) {
+ $('.guide>.tips').text(sz_msg);
+ }
+ break;
+ }
+
+ if ($('.guide>.tips').css('display') == "none") {
+ $('.guide>.tips').fadeIn(500, function() {
+ //SHOW NEWS
+ if (_newsInfo == null || Object.keys(_newsInfo).length == 0) {
+ if ($('.news').css('display') != "none") {
+ $('.news').hide();
+ }
+ } else {
+ if ($('.news').css('display') != "none") {
+ if ($('.news>.newsctz #hoteltv-news-ticker').children().length > 0) {
+ $('.news>.newsctz #hoteltv-news-ticker').webTicker('stop');
+ $('.news').fadeOut(500);
+ }
+ }
+ }
+ });
+ }
+ } else {
+ if ($('.guide>.tips').css('display') == "block") {
+ $('.guide>.tips').fadeOut(500);
+ }
+
+ if ($('.news').css('display') != "block") {
+ if ($('.news>.newsctz #hoteltv-news-ticker').children().length > 0) {
+ $('.news>.newsctz #hoteltv-news-ticker').webTicker('stop');
+ $('.news').fadeOut(500);
+ }
+ }
+ }
+ } else {
+ //HIDE TIPS and then SHOW NEWS
+ if (_newsInfo == null || Object.keys(_newsInfo).length == 0) {
+ if ($('.news').css('display') != "none") {
+ $('.news').hide();
+ }
+ } else {
+ if ($('.guide>.tips').css('display') == "block") {
+ $('.guide>.tips').fadeOut(500, function() {
+ if ($('.news').css('display') != "block") {
+ $('.news').fadeIn(500, function() {
+ __uifxn_AppFull_BldNews();
+ $('.news>.newsctz #hoteltv-news-ticker').webTicker('cont');
+ });
+ }
+ });
+ } else {
+ if ($('.news').css('display') != "block") {
+ $('.news').fadeIn(500, function() {
+ __uifxn_AppFull_BldNews();
+ $('.news>.newsctz #hoteltv-news-ticker').webTicker('cont');
+ });
+ }
+ }
+ }
+ }
+ } else {
+ //HIDE NEWS and USER GUIDE TIPS
+ if (_newsInfo == null || Object.keys(_newsInfo).length == 0) {
+ if ($('.news').css('display') != "none") {
+ $('.news').hide();
+ }
+ }
+
+
+ if ($('.guide>.tips').css('display') != "none") {
+ $('.guide>.tips').fadeOut(500, function() {
+ if ($('.news').css('display') != "none") {
+ if ($('.news>.newsctz #hoteltv-news-ticker').children().length > 0) {
+ $('.news>.newsctz #hoteltv-news-ticker').webTicker('stop');
+ $('.news').fadeOut(500);
+ }
+ }
+ });
+ }
+
+ }
+ }
+
+
+ /**
+ * HotelTV UI Wrapper Function::> received event handling function
+ * @param {boolean} _evt event
+ */
+ function __uifxn_AppFull_OnKeyDnEvt_MmSel(_evt) {
+ let _program = HotelTV.tvguide.program;
+ let _state = HotelTV.state;
+
+ if ((_program[(_evt.page.index + 1)].type == "weather") || (_program[(_evt.page.index + 1)].type == "flight")) {
+ __uifxn_AppFull_ShowMMHotKeyBtn(false);
+ } else {
+ __uifxn_AppFull_ShowMMHotKeyBtn(true);
+ }
+
+ //console.log(`Evnt: ${_evt.item.index} Of ${_evt.item.count} page::> ${_evt.page.index} of ${_evt.page.count}`);
+ //Shows Up Weather Contents
+ if (_program[(_evt.page.index + 1)].type == "weather") {
+ if ($('.main .mm .weather').css("display") == "none") {
+ $('.main .mm .weather').fadeIn(1000);
+ }
+ } else {
+ if ($('.main .mm .weather').css("display") != "none") {
+ $('.main .mm .weather').fadeOut(300);
+ }
+ }
+
+ //Shows Up Flight Contents
+ if (_program[(_evt.page.index + 1)].type == "flight") {
+ if ($('.main .mm .flight').css("display") == "none") {
+ $('.main .mm .flight').fadeIn(1000, () => {
+ $(document.activeElement).keydown(function(_evt) {
+ let _curPos = 0;
+ let _maxHeight = 0;
+
+ switch (_evt.keyCode) {
+ case 38:
+ _curPos = $('.main .mm .flight .departure tbody#record').scrollTop();
+ _maxHeight = $('.main .mm .flight .departure tbody#record')[0].scrollHeight;
+ _curPos = (_curPos - 50) < 0 ? 0 : (_curPos - 50);
+ $('.main .mm .flight tbody#record').scrollTop(_curPos);
+ break;
+ case 40:
+ _curPos = $('.main .mm .flight .departure tbody#record').scrollTop();
+ _maxHeight = $('.main .mm .flight .departure tbody#record')[0].scrollHeight;
+ _curPos = (_curPos + 50) > _maxHeight ? _maxHeight : (_curPos + 50);
+ $('.main .mm .flight tbody#record').scrollTop(_curPos);
+ break;
+ }
+ });
+ });
+ }
+ } else {
+ if ($('.main .mm .flight').css("display") != "none") {
+ if ($(".main .mm .flight tbody#record").length > 0) {
+ $('.main .mm .flight tbody#record').scrollTop(0);
+ }
+ $('.main .mm .flight').fadeOut(300, () => {
+ $(document.activeElement).off('keydown');
+ });
+ }
+ }
+ $('#lst_mmbg').trigger("to.owl.carousel", [_evt.page.index, 1000, true]);
+ }
+
+
+
+ /**
+ * HotelTV UI Wrapper Function::> Show Top Widjet Weather
+ * @param {boolean} _en show/hide
+ */
+ function __uifxn_AppFull_Widjet_ShowWeather(_en) {
+ let _weather = HotelTV.weather;
+ $('.widjet .top .weather #icon').css({ "background-image": "url(" + _weather.smallicon_image[_weather.item.condition.code] + ")" });
+ $('.widjet .top .weather #temp').text(_weather.item.condition.temp + "°C");
+ $('.widjet .top .weather').show();
+ }
+
+
+ /**
+ * HotelTV UI Wrapper Function::> Build Main Menu::> Flight
+ */
+ function __uifxn_AppFull_MM_BldFlight() {
+ let _flight = HotelTV.flight;
+ let _state = HotelTV.state;
+ let _trTbl = HotelTV.translation;
+ let _curDaTm = new Date();
+ const ar_tdItem = ['airline', 'flight', 'scheduled', 'origin', 'destination', 'type', 'gate', 'status']
+
+
+ $('.main .mm .flight .departure #title').text(_trTbl.ui.flight.title.departure[_state.lang]);
+ $('.main .mm .flight .arrival #title').text(_trTbl.ui.flight.title.arrival[_state.lang]);
+
+ let _tblHdr = $('.main .mm .flight table th')
+ for (let _i = 0; _i < _tblHdr.length; ++_i) {
+ if (_tblHdr[_i].id == "airline") {
+ _tblHdr[_i].innerText = _trTbl.ui.flight.title.airline[_state.lang];
+ } else if (_tblHdr[_i].id == "flight") {
+ _tblHdr[_i].innerText = _trTbl.ui.flight.title.flight_no[_state.lang];
+ } else if (_tblHdr[_i].id == "scheduled") {
+ _tblHdr[_i].innerText = _trTbl.ui.flight.title.scheduled[_state.lang];
+ } else if (_tblHdr[_i].id == "origin") {
+ _tblHdr[_i].innerText = _trTbl.ui.flight.title.origin[_state.lang];
+ } else if (_tblHdr[_i].id == "destination") {
+ _tblHdr[_i].innerText = _trTbl.ui.flight.title.destination[_state.lang];
+ } else if (_tblHdr[_i].id == "type") {
+ _tblHdr[_i].innerText = _trTbl.ui.flight.title.classification[_state.lang];
+ } else if (_tblHdr[_i].id == "gate") {
+ _tblHdr[_i].innerText = _trTbl.ui.flight.title.boarding_gate[_state.lang];
+ } else if (_tblHdr[_i].id == "status") {
+ _tblHdr[_i].innerText = _trTbl.ui.flight.status[_state.lang];
+ }
+ }
+
+ //Delete all table record for departure & arrival
+ let _el_departure_tbl_rec = document.querySelector('.main .mm .flight .departure table #record');
+ let _el_arrival_tbl_rec = document.querySelector('.main .mm .flight .arrival table #record');
+
+ //Delete all table record for departure & arrival
+ $('.main .mm .flight .departure table tr#record').remove();
+ $('.main .mm .flight .arrival table tr#record').remove();
+
+ for (let _i = 0; _i < _flight.count; _i++) {
+ let _schOrg = new Date();
+ let _schEdt = new Date();
+ let _flitem = _flight.items[_i];
+
+ //let _sTmOrg = _flitem.std.length != 4 ? null : ;
+ //let _sTmChanged = _flitem.etd;
+
+ if (_flitem.std.length != 4) {
+ console.log("Flight Schedule org time is NULL");
+ } else {
+ _schOrg.setHours(Number(_flitem.std.charAt(0) + _flitem.std.charAt(1)));
+ _schOrg.setMinutes(Number(_flitem.std.charAt(2) + _flitem.std.charAt(3)));
+ }
+
+ if (_flitem.std.length != 4) {
+ console.log("Flight Schedule edited time is NULL");
+ } else {
+ _schEdt.setHours(Number(_flitem.std.charAt(0) + _flitem.std.charAt(1)));
+ _schEdt.setMinutes(Number(_flitem.std.charAt(2) + _flitem.std.charAt(3)));
+ }
+
+
+
+ let diffMs = (_schOrg - _curDaTm); // milliseconds between now & Christmas
+ // let diffDays = Math.floor(diffMs / 86400000); // days
+ // let diffHrs = Math.floor((diffMs % 86400000) / 3600000); // hours
+ // let diffMins = Math.round(((diffMs % 86400000) % 3600000) / 60000); // minutes
+ // console.log(diffDays + " days, " + diffHrs + " hours, " + diffMins + " minutes");
+ let diffMins = Math.round(diffMs / 60000);
+ //console.log("TDiff::> " + diffMins);
+
+ if ((-60 < diffMins) && (diffMins < 120)) {
+ if (_flitem.io == "O") {
+ let _el_tr = document.createElement('tr');
+ _el_tr.setAttribute("id", "record");
+ ar_tdItem.forEach(_itm => {
+ let _el_td = document.createElement('td');
+ _el_td.setAttribute("id", _itm);
+ if (_itm == "airline") {
+ _el_td.innerText = HotelTV.ui_utils.Get_Airline(_trTbl.ui.flight.airlines, _flitem.airline, _state.lang);
+ } else if (_itm == "flight") {
+ _el_td.innerText = _flitem.airFln;
+ } else if (_itm == "scheduled") {
+ _el_td.innerText = _flitem.std.charAt(0) + _flitem.std.charAt(1) + ":" + _flitem.std.charAt(2) + _flitem.std.charAt(3) + " - ";
+ _el_td.innerText += _flitem.etd.charAt(0) + _flitem.etd.charAt(1) + ":" + _flitem.etd.charAt(2) + _flitem.etd.charAt(3);
+ } else if (_itm == "origin") {
+ _el_td.innerText = HotelTV.ui_utils.Get_Airport(_trTbl.ui.flight.city, _flitem.boarding, _state.lang);
+ } else if (_itm == "destination") {
+ _el_td.innerText = HotelTV.ui_utils.Get_Airport(_trTbl.ui.flight.city, _flitem.arrived, _state.lang);
+ } else if (_itm == "type") {
+ _el_td.innerText = _trTbl.ui.flight.line[_flitem.line][_state.lang];
+ } else if (_itm == "gate") {
+ _el_td.innerText = _flitem.gate;
+ } else if (_itm == "status") {
+ _el_td.innerText = HotelTV.ui_utils.Get_FlightStatus(_trTbl.ui.flight.result, _flitem.rmk, _state.lang);
+ }
+ _el_tr.appendChild(_el_td);
+ });
+ _el_departure_tbl_rec.appendChild(_el_tr);
+ } else {
+ let _el_tr = document.createElement('tr');
+ _el_tr.setAttribute("id", "record");
+ ar_tdItem.forEach(_itm => {
+ let _el_td = document.createElement('td');
+ _el_td.setAttribute("id", _itm);
+ if (_itm == "airline") {
+ _el_td.innerText = HotelTV.ui_utils.Get_Airline(_trTbl.ui.flight.airlines, _flitem.airline, _state.lang);
+ } else if (_itm == "flight") {
+ _el_td.innerText = _flitem.airFln;
+ } else if (_itm == "scheduled") {
+ _el_td.innerText = _flitem.std.charAt(0) + _flitem.std.charAt(1) + ":" + _flitem.std.charAt(2) + _flitem.std.charAt(3) + " - ";
+ _el_td.innerText += _flitem.etd.charAt(0) + _flitem.etd.charAt(1) + ":" + _flitem.etd.charAt(2) + _flitem.etd.charAt(3);
+ } else if (_itm == "origin") {
+ _el_td.innerText = HotelTV.ui_utils.Get_Airport(_trTbl.ui.flight.city, _flitem.boarding, _state.lang);
+ } else if (_itm == "destination") {
+ _el_td.innerText = HotelTV.ui_utils.Get_Airport(_trTbl.ui.flight.city, _flitem.arrived, _state.lang);
+ } else if (_itm == "type") {
+ if (_trTbl.ui.flight.line[_flitem.line]) {
+ _el_td.innerText = _trTbl.ui.flight.line[_flitem.line][_state.lang];
+ }
+ } else if (_itm == "gate") {
+ _el_td.innerText = _flitem.gate;
+ } else if (_itm == "status") {
+ _el_td.innerText = HotelTV.ui_utils.Get_FlightStatus(_trTbl.ui.flight.result, _flitem.rmk, _state.lang);
+ }
+ _el_tr.appendChild(_el_td);
+ });
+ _el_arrival_tbl_rec.appendChild(_el_tr);
+ }
+ }
+ }
+ $('.main .mm .flight #caution').text(_trTbl.ui.flight.caution.body[_state.lang]);
+ }
+
+ /**
+ * HotelTV UI Wrapper Function::> Build Main Menu::> Weather
+ */
+ function __uifxn_AppFull_MM_BldWeather() {
+ let _trTbl = HotelTV.translation;
+ let _weather = HotelTV.weather;
+ let _cur_cond = _weather.item.condition
+ let _state = HotelTV.state;
+ let _elWeatherRoot = $('.main .mm .weather');
+ let _elWeatherToday = _elWeatherRoot.children('.today');
+ let _elWeatherForcast = _elWeatherRoot.children('.forcast');
+ let _elWeatherCation = _elWeatherRoot.children('#caution');
+
+ _elWeatherRoot.children('.location').text(_trTbl.system.locale.city[_weather.location][_state.lang] || null);
+ _elWeatherToday.children('#temp_cur').text(_weather.item.condition.temp + "°C");
+ _elWeatherToday.children('#temp_minmax').text(_weather.item.forecast[0].low + "°C/" + _weather.item.forecast[0].high + " °C");
+ _elWeatherToday.children('.detail').children('#discription').text(_trTbl.ui.weather.cond[_cur_cond.code][_state.lang]);
+ _elWeatherToday.children('.detail').children('#img_status').css('background-image', 'url(' + _weather.icon_image[_cur_cond.code] + ')');
+ _elWeatherToday.children('.detail').children('#humidity').children('#icon').css('background-image', 'url(./images/icons/icon_humidity.png)');
+ _elWeatherToday.children('.detail').children('#humidity').children('#value').text(_weather.daily['1'].main.humidity + " %");
+ _elWeatherToday.children('.detail').children('#wind').children('#icon').css('background-image', 'url(./images/icons/icon_wind.png)');
+ _elWeatherToday.children('.detail').children('#wind').children('#value').text(HotelTV.ui_utils.Weather_GetWindReport(_trTbl.ui.weather.wind_dir, _weather.wind.speed, _weather.wind.direction, _state.lang));
+
+ //Daily Summary
+ _elWeatherForcast.children('.daily').children('#title').text(_trTbl.ui.weather.fc_today[_state.lang]);
+ let _eltbl_fc_daily_items = _elWeatherForcast.children('.daily').children('ul').children('li');
+ for (let _idx = 0; _idx < _eltbl_fc_daily_items.length; ++_idx) {
+ let _wData = _weather.daily[Number(_idx) + 1];
+ let _time = _wData.dt_txt.split(' ')[1];
+ let _temp = _wData.main.temp;
+ //OpenWeather API관련 아이콘 URL을 가져오는 방법은 아래 링크 참조:
+ //https://openweathermap.org/weather-conditions
+ $(_eltbl_fc_daily_items[_idx]).css('background-image', 'url(http://openweathermap.org/img/wn/' + _wData.weather.icon + '@2x.png)');
+ //$(_eltbl_fc_daily_items[_idx]).css('background-image', 'url(' + _weather.icon_image[_wData.weather.id] + ')');
+
+ $(_eltbl_fc_daily_items[_idx].children.time)[0].innerText = _time.split(":")[0] + ":" + _time.split(":")[1];
+ $(_eltbl_fc_daily_items[_idx].children.temp)[0].innerText = _temp.toString() + " °C";
+ }
+
+ //Weekly Summary
+ _elWeatherForcast.children('.weekly').children('#title').text(_trTbl.ui.weather.fc_weekly[_state.lang]);
+ let _eltbl_fc_weekly_items = _elWeatherForcast.children('.weekly').children('ul').children('li');
+ for (let _idx = 0; _idx < _eltbl_fc_weekly_items.length; ++_idx) {
+ let _wData = _weather.item.forecast[Number(_idx)];
+ $(_eltbl_fc_weekly_items[_idx]).css('background-image', 'url(' + _weather.icon_image[_wData.code] + ')');
+ $(_eltbl_fc_weekly_items[_idx].children.date)[0].innerText = _trTbl.system.days[_wData.day][_state.lang];
+ $(_eltbl_fc_weekly_items[_idx].children.temp)[0].innerText = _wData.low + " °C /" + _wData.high + " °C";
+ }
+ _elWeatherCation.text(_trTbl.ui.weather.caution.body[_state.lang]);
+ }
+
+ /**
+ * HotelTV UI[AppFull] Wrapper Function::> Buildup main menu and main bg
+ * @param {boolean} uri_img background image url
+ */
+ function __uifxn_AppFull_BldPage_Main() {
+ let _program = HotelTV.tvguide.program;
+ let _weather = HotelTV.weather;
+ let _state = HotelTV.state;
+ let _mmcnt = 0;
+
+ _mmcnt = _program.length;
+ //_mm_width = 1920 / (_mmcnt - 1);
+ _mm_width = 266;
+
+ // 초기 메인 메뉴 KEY설정
+ _state.menu.stage = "preparing_main";
+ if (_state.menu.main.cur == null) {
+ _state.menu.main.cur = Object.keys(_program)[0];
+ }
+
+ // 메인 메뉴 셀렉터 노드를 동적으로 구성
+ let _div_mm_slist = document.querySelector('#lst_mmsel');
+ for (let _mm_idx = 1; _mm_idx <= _program.length; _mm_idx++) {
+ let _div_mm_item = document.createElement('div');
+ _div_mm_item.className = 'item';
+ _div_mm_item.id = _program[_mm_idx].id;
+ _div_mm_item.setAttribute("mmid", _mm_idx);
+ _div_mm_item.style.height = '92px';
+ // _div_mm_item.style.width = _mm_width + 'px';
+
+ // Append Sub elements::title
+ let _mm_item_title = document.createElement('div');
+ _mm_item_title.setAttribute("id", "mm_item_title");
+ if (_program[_mm_idx].title_show && _program[_mm_idx].title_show == true) {
+ _mm_item_title.textContent = _program[_mm_idx].title[_state.lang];
+ } else {
+ _mm_item_title.textContent = _program[_mm_idx].title[_state.lang];
+ }
+
+ // Append Sub elements::icon
+ let _mm_item_icon = document.createElement('div');
+ _mm_item_icon.setAttribute("id", "mm_item_icon");
+ let _sz_styleOpt = "--icon_unfocus: url(" + _program[_mm_idx].unfocusIcon.file.download + "); ";
+ _sz_styleOpt += "--icon_focus: url(" + _program[_mm_idx].focusIcon.file.download + "); ";
+ //_sz_styleOpt += "background-repeat: no-repeat; background-position: center bottom; background-size: 100% 100%; ";
+ _sz_styleOpt += "background-repeat: no-repeat; background-position: center bottom;";
+ _mm_item_icon.setAttribute("style", _sz_styleOpt);
+
+ _div_mm_item.appendChild(_mm_item_icon);
+ _div_mm_item.appendChild(_mm_item_title);
+
+ _div_mm_slist.appendChild(_div_mm_item);
+ }
+
+ // 메인 메뉴 백그라운드 이미지 노드를 동적으로 구성
+ let _div_mm_bglist = document.querySelector('#lst_mmbg');
+ for (let _mm_idx = 1; _mm_idx <= _program.length; _mm_idx++) {
+ let _div_mm_item = document.createElement('div');
+ let _sz_styleOpt = null;
+
+ _div_mm_item.className = 'item';
+ _div_mm_item.id = 'mmbg_' + _program[_mm_idx].name.replace(/\s/g, '').toLowerCase();
+ _div_mm_item.setAttribute("mmid", _mm_idx);
+ if (_program[_mm_idx].type.toLowerCase() == "weather") {
+ if (_weather != null) {
+ _sz_styleOpt = "background-image: url(" + _weather.background_image[_weather.item.condition.code] + "); ";
+ } else {
+ _sz_styleOpt = "background-image: url(" + _program[_mm_idx].background.file.download + "); ";
+ }
+ } else {
+ _sz_styleOpt = "background-image: url(" + _program[_mm_idx].background.file.download + "); ";
+ }
+ _sz_styleOpt += "background-repeat: no-repeat; background-position: center center; background-size: 100% 100%; ";
+ _div_mm_item.setAttribute("style", _sz_styleOpt);
+
+ _div_mm_bglist.appendChild(_div_mm_item);
+ }
+ _hndl_mmBg = $('#lst_mmbg');
+ _hndl_mmBg.owlCarousel({
+ center: true,
+ items: 1, //Number of Items on Screen what you want
+ loop: true,
+ margin: 0,
+ smartSpeed: 1000,
+ lazyLoad: true,
+ mouseDrag: false,
+ touchDrag: false,
+ pullDrag: false,
+ freeDrag: false,
+ startPosition: Number(_state.menu.cur) - 1,
+ });
+ $('.main .mm .bg').show(function() {
+ //호텔 로고 출력
+ $('.widjet .top .hotellogo').css({ "background-image": "url(" + HotelTV.hotelinfo.subLogo.download + ")" });
+
+ //상단 날씨 아이콘 및 온도 표시
+ __uifxn_AppFull_Widjet_ShowWeather();
+
+ // //상단 시계 표시
+ _hndl_widget_topTime = setInterval(() => {
+ let _szCurTm = HotelTV.ui_utils.GetCur_DateTime();
+ //console.log("_szCurTm=>" + _szCurTm);
+ $('.widjet .top .datetime .time').text(_szCurTm.time);
+ $('.widjet .top .datetime .date').text(_szCurTm.date);
+ }, 1000);
+
+ //Weather Contents Buildup
+ __uifxn_AppFull_MM_BldWeather();
+
+ //Flight Contents Buildup
+ __uifxn_AppFull_MM_BldFlight();
+
+ //Build Brochures
+ __uifxn_AppFull_BuildBrochure();
+
+ //Build Amenity
+ __uifxn_AppFull_BuildAmenity();
+
+ //Build Room Service
+ __uifxn_AppFull_BuildRoomService();
+
+ //위젯 표시
+ $('.widjet').show();
+ });
+
+
+
+ _hndl_mmSel = $('#lst_mmsel');
+ _hndl_mmSel.owlCarousel({
+ center: true,
+ items: 5, //Number of Items on Screen what you want
+ loop: true,
+ margin: 0,
+ smartSpeed: 10,
+ autoWidth: false,
+ mouseDrag: false,
+ touchDrag: false,
+ pullDrag: false,
+ freeDrag: false,
+ startPosition: Number(_state.menu.cur) - 1,
+ });
+ $('.main .mm .slider').fadeIn(500, function() {
+ if (_hndl_tmrUgMngr == null) {
+ _hndl_tmrUgMngr = setInterval(__uifxn_AppFull_GuideBarUiMngr, 1000);
+ console.log("TMR::>Created...");
+ }
+ $('.main .mm .slider .owl-item').addClass('unfocus');
+ $('#lst_mmsel').trigger("to.owl.carousel", [0, 10, true]);
+ $('#lst_mmsel').trigger('translate.owl.carousel', [0, 500, true]);
+
+ HotelTV.ui_utils.SetBusy(false);
+ _state.menu.stage = "main";
+ });
+
+ $(document).on('keydown', function(_evt) { //attach event listener
+ let _opening = HotelTV.opening;
+
+ if (_state.menu.stage == "main") {
+ console.log("MM KEY EVENT::> " + _evt.keyCode);
+ if (_evt.keyCode == 37) {
+ $('#lst_mmsel').trigger('prev.owl', 700)
+ } else if (_evt.keyCode == 39) {
+ $('#lst_mmsel').trigger('next.owl', 700)
+ } else if (_evt.keyCode == 13) {
+ // 서브 메뉴 빌드 및 화면 전환
+ __uifxn_AppFull_ShowMMHotKeyBtn(false);
+ if (_program[Number(_state.menu.main.cur)].type.toLowerCase() == "normal") {
+ if (_program[Number(_state.menu.main.cur)].style.toLowerCase() == "none") {
+ console.log("It's Top level contents...");
+ } else if (_program[Number(_state.menu.main.cur)].style.toLowerCase() == "content") {
+ console.log("Preparing General sub contents...");
+ } else if (_program[Number(_state.menu.main.cur)].style.toLowerCase() == "submenu") {
+ console.log("Preparing General sub menu...");
+ __uifxn_AppFull_BldPage_SubGeneral();
+ }
+ } else if (_program[Number(_state.menu.main.cur)].type.toLowerCase() == "mypage") {
+ console.log("Preparing Mypage sub menu...");
+ __uifxn_AppFull_BuildMyPage();
+ } else if (_program[Number(_state.menu.main.cur)].type.toLowerCase() == "tv") {
+ console.log("Preparing TV sub menu...");
+ __uifxn_AppFull_BldPage_SubTV();
+ } else if (_program[Number(_state.menu.main.cur)].type.toLowerCase() == "application") {
+ console.log("Preparing TV APP::>" + _program[Number(_state.menu.main.cur)].service);
+ if (_program[Number(_state.menu.main.cur)].service == "youtube") {
+ console.log(`Type:${_program[Number(_state.menu.main.cur)].type} preparing WIFI AP...`);
+ HotelTV.hcap.SetSoftAp({
+ "enable": true,
+ "ssid": "TVWIFI-" + HotelTV.guestinfo.room,
+ "password": "12345678",
+ });
+ }
+ HotelTV.hcap.LaunchPreApp(_program[Number(_state.menu.main.cur)].service, null);
+ } else {
+ console.log(`Type:${_program[Number(_state.menu.main.cur)].type} doen's have sub menu...`);
+ }
+ } else if (_evt.keyCode == 403) {
+ // RED BUTTON
+ if ("red" in _state.hotkey.mm) {
+ $('.guide>.tips').stop().animate({ backgroundColor: "rgba(0,0,0,0.8)" }, 500, function() {
+ if (_state.hotkey.mm.red.type == "brochure") {
+ $('.popup .hotkey_mm_red').fadeIn(1000, function() {
+ _state.menu.stage = "hotkey_mm_red";
+ __uifxn_AppFull_ShowMMHotKeyBtn(false);
+ });
+ } else if (_state.hotkey.mm.red.type == "amenity") {
+ $('.popup .amenity').show(0, function() {
+ $('.popup .amenity').animate({ top: 96, left: 64 }, 500, () => {
+ _state.menu.stage = "hotkey_mm_amenity";
+ __uifxn_AppFull_ShowMMHotKeyBtn(false);
+ });
+ });
+ } else if (_state.hotkey.mm.red.type == "roomservice") {
+ $('.popup .roomservice').show(0, function() {
+ $('.popup .roomservice').animate({ top: 96, left: 64 }, 500, () => {
+ _state.menu.stage = "hotkey_mm_roomservice";
+ __uifxn_AppFull_ShowMMHotKeyBtn(false);
+ });
+ });
+ }
+ });
+ }
+ } else if (_evt.keyCode == 404) {
+ // GREEN BUTTON
+ if ("green" in _state.hotkey.mm) {
+ $('.guide>.tips').stop().animate({ backgroundColor: "rgba(0,0,0,0.8)" }, 500, function() {
+ if (_state.hotkey.mm.green.type == "brochure") {
+ $('.popup .hotkey_mm_green').fadeIn(1000, function() {
+ _state.menu.stage = "hotkey_mm_green";
+ __uifxn_AppFull_ShowMMHotKeyBtn(false);
+ });
+ } else if (_state.hotkey.mm.green.type == "amenity") {
+ $('.popup .amenity').show(0, function() {
+ $('.popup .amenity').animate({ top: 96, left: 64 }, 500, () => {
+ _state.menu.stage = "hotkey_mm_amenity";
+ __uifxn_AppFull_ShowMMHotKeyBtn(false);
+ });
+ });
+ } else if (_state.hotkey.mm.green.type == "roomservice") {
+ $('.popup .roomservice').show(0, function() {
+ $('.popup .roomservice').animate({ top: 96, left: 64 }, 500, () => {
+ _state.menu.stage = "hotkey_mm_roomservice";
+ __uifxn_AppFull_ShowMMHotKeyBtn(false);
+ });
+ });
+ }
+ });
+ }
+ } else if (_evt.keyCode == 405) {
+ // YELLOW BUTTON
+ if ("yellow" in _state.hotkey.mm) {
+ $('.guide>.tips').stop().animate({ backgroundColor: "rgba(0,0,0,0.8)" }, 500, function() {
+ if (_state.hotkey.mm.yellow.type == "brochure") {
+ $('.popup .hotkey_mm_yellow').fadeIn(1000, function() {
+ _state.menu.stage = "hotkey_mm_yellow";
+ __uifxn_AppFull_ShowMMHotKeyBtn(false);
+ });
+ } else if (_state.hotkey.mm.yellow.type == "amenity") {
+ $('.popup .amenity').show(0, function() {
+ $('.popup .amenity').animate({ top: 96, left: 64 }, 500, () => {
+ _state.menu.stage = "hotkey_mm_amenity";
+ __uifxn_AppFull_ShowMMHotKeyBtn(false);
+ });
+ });
+ } else if (_state.hotkey.mm.yellow.type == "roomservice") {
+ $('.popup .roomservice').show(0, function() {
+ $('.popup .roomservice').animate({ top: 96, left: 64 }, 500, () => {
+ _state.menu.stage = "hotkey_mm_roomservice";
+ __uifxn_AppFull_ShowMMHotKeyBtn(false);
+ });
+ });
+ }
+ });
+ }
+ } else if (_evt.keyCode == 406) {
+ // BLUE BUTTON
+ if ("blue" in _state.hotkey.mm) {
+ $('.guide>.tips').stop().animate({ backgroundColor: "rgba(0,0,0,0.8)" }, 500, function() {
+ if (_state.hotkey.mm.blue.type == "brochure") {
+ $('.popup .hotkey_mm_blue').fadeIn(1000, function() {
+ _state.menu.stage = "hotkey_mm_blue";
+ __uifxn_AppFull_ShowMMHotKeyBtn(false);
+ });
+ } else if (_state.hotkey.mm.blue.type == "amenity") {
+ $('.popup .amenity').show(0, function() {
+ $('.popup .amenity').animate({ top: 96, left: 64 }, 500, () => {
+ _state.menu.stage = "hotkey_mm_amenity";
+ __uifxn_AppFull_ShowMMHotKeyBtn(false);
+ });
+ });
+ } else if (_state.hotkey.mm.blue.type == "roomservice") {
+ $('.popup .roomservice').show(0, function() {
+ $('.popup .roomservice').animate({ top: 96, left: 64 }, 500, () => {
+ _state.menu.stage = "hotkey_mm_roomservice";
+ __uifxn_AppFull_ShowMMHotKeyBtn(false);
+ });
+ });
+ }
+ });
+ }
+ }
+ } else if (_state.menu.stage == "hotkey_mm_red") {
+ console.log("HOTKEY(MM:RED) KEY EVENT::> " + _evt.keyCode);
+ if (_evt.keyCode == 37) {
+ $('#lst_hotkey_mm_red').trigger('prev.owl')
+ } else if (_evt.keyCode == 39) {
+ $('#lst_hotkey_mm_red').trigger('next.owl')
+ } else if (_evt.keyCode == 461) {
+ $('.popup .hotkey_mm_red').fadeOut(1000, function() {
+ $('.popup .hotkey_mm_red').stop().animate({ backgroundColor: "rgba(0,0,0,0.0)" }, 500, function() {
+ $('.popup .hotkey_mm_red').css({ "background-color": "" });
+ _state.menu.stage = "main";
+ __uifxn_AppFull_ShowMMHotKeyBtn(true);
+ });
+ });
+ }
+ } else if (_state.menu.stage == "hotkey_mm_green") {
+ console.log("HOTKEY(MM:GREEN) KEY EVENT::> " + _evt.keyCode);
+ if (_evt.keyCode == 37) {
+ $('#lst_hotkey_mm_green').trigger('prev.owl')
+ } else if (_evt.keyCode == 39) {
+ $('#lst_hotkey_mm_green').trigger('next.owl')
+ } else if (_evt.keyCode == 461) {
+ $('.popup .hotkey_mm_green').fadeOut(1000, function() {
+ $('.popup .hotkey_mm_green').stop().animate({ backgroundColor: "rgba(0,0,0,0.0)" }, 500, function() {
+ $('.popup .hotkey_mm_green').css({ "background-color": "" });
+ _state.menu.stage = "main";
+ __uifxn_AppFull_ShowMMHotKeyBtn(true);
+ });
+ });
+ }
+ } else if (_state.menu.stage == "hotkey_mm_yellow") {
+ console.log("HOTKEY(MM:YELLOW) KEY EVENT::> " + _evt.keyCode);
+ if (_evt.keyCode == 37) {
+ console.log("LEFT");
+ } else if (_evt.keyCode == 38) {
+ console.log("UP");
+ } else if (_evt.keyCode == 39) {
+ console.log("RIGHT");
+ } else if (_evt.keyCode == 40) {
+ console.log("DOWN");
+ } else if (_evt.keyCode == 461) {
+ $('.popup .hotkey_mm_yellow').fadeOut(1000, function() {
+ $('.popup .hotkey_mm_yellow').stop().animate({ backgroundColor: "rgba(0,0,0,0.0)" }, 500, function() {
+ $('.popup .hotkey_mm_yellow').css({ "background-color": "" });
+ _state.menu.stage = "main";
+ __uifxn_AppFull_ShowMMHotKeyBtn(true);
+ });
+ });
+ }
+ } else if (_state.menu.stage == "hotkey_mm_blue") {
+ console.log("HOTKEY(MM:BLUE) KEY EVENT::> " + _evt.keyCode);
+ if (_evt.keyCode == 37) {
+ console.log("LEFT");
+ } else if (_evt.keyCode == 38) {
+ console.log("UP");
+ } else if (_evt.keyCode == 39) {
+ console.log("RIGHT");
+ } else if (_evt.keyCode == 40) {
+ console.log("DOWN");
+ } else if (_evt.keyCode == 461) {
+ $('.popup .hotkey_mm_blue').fadeOut(1000, function() {
+ $('.popup .hotkey_mm_blue').stop().animate({ backgroundColor: "rgba(0,0,0,0.0)" }, 500, function() {
+ $('.popup .hotkey_mm_blue').css({ "background-color": "" });
+ _state.menu.stage = "main";
+ __uifxn_AppFull_ShowMMHotKeyBtn(true);
+ });
+ });
+ }
+ } else if (_state.menu.stage == "hotkey_mm_amenity") {
+ console.log("HOTKEY(MM:AMENITY) KEY EVENT::> " + _evt.keyCode);
+ if (_evt.keyCode == 37) {
+ console.log("LEFT");
+ __uifxn_AppFull_HandleAmenity("del", false, false);
+ } else if (_evt.keyCode == 38) {
+ console.log("UP");
+ __uifxn_AppFull_HandleAmenity("up", false, false);
+ } else if (_evt.keyCode == 39) {
+ console.log("RIGHT");
+ __uifxn_AppFull_HandleAmenity("add", false, false);
+ } else if (_evt.keyCode == 40) {
+ console.log("DOWN");
+ __uifxn_AppFull_HandleAmenity("down", false, false);
+ } else if (_evt.keyCode == 13) {
+ console.log("ENTER");
+ if (_state.hotkey.mm[_opening.amenity.button].status.last_CartBtn_idx == "cancel") {
+ // Move to top of item list
+ $('.popup .amenity .items').animate({ scrollTop: 0 }, 0);
+ $('.popup .amenity').animate({ top: 96, left: -560 }, 500, () => {
+ $('.popup .amenity>.items').animate({ scrollTop: 0 }, 0, () => {
+ _state.menu.stage = "main";
+ $('.popup .amenity').hide(0, 'linear', () => {
+ // HOTKEY STATUS 리셋
+ __uifxn_AppFull_HandleAmenity("reset", true, false);
+ __uifxn_AppFull_ShowMMHotKeyBtn(true);
+ });
+ });
+ });
+ } else if (_state.hotkey.mm[_opening.amenity.button].status.last_CartBtn_idx == "order") {
+ $('.popup .amenity').animate({ top: 96, left: -560 }, 500, () => {
+ // Move to top of item list
+ $('.popup .amenity>.items').animate({ scrollTop: 0 }, 0, () => {
+ _state.menu.stage = "main";
+ $('.popup .amenity').hide(0, 'linear', () => {
+ // HOTKEY STATUS 리셋
+ __uifxn_AppFull_HandleAmenity("reset", false, true);
+ __uifxn_AppFull_ShowMMHotKeyBtn(true);
+ });
+ });
+ });
+ } else if (_state.hotkey.mm[_opening.amenity.button].status.last_CartBtn_idx == "details") {
+ $('.popup .amenity').animate({ scrollTop: $('.popup .amenity').prop('offsetHeight') }, 500, () => {
+ // scroll to show amenity order details
+ __uifxn_AppFull_HandleAmenity("enter", false, false);
+ _state.menu.stage = "hotkey_mm_amenity_order_details";
+ __uifxn_AppFull_BuildAmenityOrderDetails();
+ });
+ }
+ } else if (_evt.keyCode == 461) {
+ $('.popup .amenity').animate({ top: 96, left: -560 }, 500, () => {
+ // Move to top of item list
+ $('.popup .amenity>.items').animate({ scrollTop: 0 }, 0, () => {
+ _state.menu.stage = "main";
+ $('.popup .amenity').hide(0, 'linear', () => {
+ // HOTKEY STATUS 리셋
+ __uifxn_AppFull_HandleAmenity("reset", true, false);
+ __uifxn_AppFull_ShowMMHotKeyBtn(true);
+ });
+ });
+ });
+ }
+ } else if (_state.menu.stage == "hotkey_mm_amenity_order_details") {
+ console.log("HOTKEY(MM:ROOMSERVICE) KEY EVENT::> " + _evt.keyCode);
+ if (_evt.keyCode == 37) {
+ console.log("LEFT");
+ } else if (_evt.keyCode == 38) {
+ console.log("UP");
+ __uifxn_AppFull_HandleAmenity("up", false, false);
+ } else if (_evt.keyCode == 39) {
+ console.log("RIGHT");
+ } else if (_evt.keyCode == 40) {
+ console.log("DOWN");
+ __uifxn_AppFull_HandleAmenity("down", false, false);
+ } else if (_evt.keyCode == 461) {
+ $('.popup .amenity').animate({ top: 96, left: -560 }, 500, () => {
+ $('.popup .amenity').animate({ scrollTop: 0 }, 0, () => {
+ // Move to top of item list
+ $('.popup .amenity>.items').animate({ scrollTop: 0 }, 0, () => {
+ _state.menu.stage = "main";
+ $('.popup .amenity').hide(0, 'linear', () => {
+ // HOTKEY STATUS 리셋
+ __uifxn_AppFull_HandleAmenity("reset", true, false);
+ __uifxn_AppFull_ShowMMHotKeyBtn(true);
+ });
+ });
+ });
+ });
+ }
+ } else if (_state.menu.stage == "hotkey_mm_roomservice") {
+ console.log("HOTKEY(MM:ROOMSERVICE) KEY EVENT::> " + _evt.keyCode);
+ if (_evt.keyCode == 37) {
+ console.log("LEFT");
+ __uifxn_AppFull_HandleRoomservice("del", false, false);
+ } else if (_evt.keyCode == 38) {
+ console.log("UP");
+ __uifxn_AppFull_HandleRoomservice("up", false, false);
+ } else if (_evt.keyCode == 39) {
+ console.log("RIGHT");
+ __uifxn_AppFull_HandleRoomservice("add", false, false);
+ } else if (_evt.keyCode == 40) {
+ console.log("DOWN");
+ __uifxn_AppFull_HandleRoomservice("down", false, false);
+ } else if (_evt.keyCode == 13) {
+ console.log("ENTER");
+ if (_state.hotkey.mm[_opening.roomService.button].status.last_CartBtn_idx == "cancel") {
+ let _elRsMnRoot = $(`.popup .roomservice`);
+ _elRsMnRoot.children('.menu').animate({ scrollTop: 0 }, 0);
+ _elRsMnRoot.animate({ top: 96, left: -560 }, 500, () => {
+ _elRsMnRoot.children('.menu').children('.items').animate({ scrollTop: 0 }, 0, () => {
+ _state.menu.stage = "main";
+ _elRsMnRoot.hide(0, 'linear', () => {
+ // HOTKEY STATUS 리셋
+ __uifxn_AppFull_HandleRoomservice("reset", true, false);
+ __uifxn_AppFull_ShowMMHotKeyBtn(true);
+ });
+ });
+ });
+ } else if (_state.hotkey.mm[_opening.roomService.button].status.last_CartBtn_idx == "order") {
+ let _elRsMnRoot = $(`.popup .roomservice`);
+ _elRsMnRoot.children('.menu').animate({ scrollTop: 0 }, 0);
+ _elRsMnRoot.animate({ top: 96, left: -560 }, 500, () => {
+ _elRsMnRoot.children('.menu').children('.items').animate({ scrollTop: 0 }, 0, () => {
+ _state.menu.stage = "main";
+ _elRsMnRoot.hide(0, 'linear', () => {
+ // HOTKEY STATUS 리셋
+ __uifxn_AppFull_HandleRoomservice("reset", false, true);
+ __uifxn_AppFull_ShowMMHotKeyBtn(true);
+ });
+ });
+ });
+ } else if (_state.hotkey.mm[_opening.roomService.button].status.last_CartBtn_idx == "details") {
+ let _elRsMnRoot = $(`.popup .roomservice .menu`);
+ _elRsMnRoot.animate({ scrollTop: _elRsMnRoot.prop('offsetHeight') }, 500, () => {
+ // scroll to show roomservice order details
+ __uifxn_AppFull_HandleRoomservice("enter", false, false);
+ _state.menu.stage = "hotkey_mm_roomservice_order_details";
+ __uifxn_AppFull_BuildRoomserviceOrderDetails();
+ });
+ }
+ } else if (_evt.keyCode == 461) {
+ let _elRsMnRoot = $(`.popup .roomservice`);
+ _elRsMnRoot.animate({ top: 96, left: -560 }, 500, () => {
+ // Move to top of item list
+ _elRsMnRoot.children('.menu').children('.items').animate({ scrollTop: 0 }, 0, () => {
+ _state.menu.stage = "main";
+ _elRsMnRoot.hide(0, 'linear', () => {
+ // HOTKEY STATUS 리셋
+ __uifxn_AppFull_HandleRoomservice("reset", true, false);
+ __uifxn_AppFull_ShowMMHotKeyBtn(true);
+ });
+ });
+ });
+ }
+ } else if (_state.menu.stage == "hotkey_mm_roomservice_order_details") {
+ console.log("HOTKEY(MM:ROOMSERVICE) KEY EVENT::> " + _evt.keyCode);
+ if (_evt.keyCode == 37) {
+ console.log("LEFT");
+ } else if (_evt.keyCode == 38) {
+ console.log("UP");
+ __uifxn_AppFull_HandleRoomservice("up", false, false);
+ } else if (_evt.keyCode == 39) {
+ console.log("RIGHT");
+ } else if (_evt.keyCode == 40) {
+ console.log("DOWN");
+ __uifxn_AppFull_HandleRoomservice("down", false, false);
+ } else if (_evt.keyCode == 461) {
+ $('.popup .roomservice').animate({ top: 96, left: -560 }, 500, () => {
+ $('.popup .roomservice .menu').animate({ scrollTop: 0 }, 0, () => {
+ // Move to top of item list
+ $('.popup .roomservice .menu>.items').animate({ scrollTop: 0 }, 0, () => {
+ _state.menu.stage = "main";
+ $('.popup .roomservice').hide(0, 'linear', () => {
+ // HOTKEY STATUS 리셋
+ __uifxn_AppFull_HandleRoomservice("reset", true, false);
+ __uifxn_AppFull_ShowMMHotKeyBtn(true);
+ });
+ });
+ });
+ });
+ }
+ }
+ });
+
+ _hndl_mmSel.on('change.owl.carousel', function(event) {
+ // Update HotelTV menu status
+ let _state = HotelTV.state;
+ _state.menu.main.prev = Object.keys(_program)[event.page.index];
+ });
+
+ _hndl_mmSel.on('changed.owl.carousel', function(event) {
+ // Update HotelTV menu status
+ let _state = HotelTV.state;
+ _state.menu.main.cur = Object.keys(_program)[event.page.index];
+ __uifxn_AppFull_OnKeyDnEvt_MmSel(event);
+ //console.log("MAIN IDX::>" + _state.menu.main.cur);
+ });
+
+ _hndl_mmSel.on('translate.owl.carousel', function(event) {
+ /** 메뉴 셀렉터 좌/우 헨들링 및 이펙트 */
+ //console.log("MM::> Translaged Event");
+ let idx = 0;
+ if (typeof event.item != 'undefined') {
+ idx = event.item.index;
+ } else {
+ idx = $('.main .mm .slider .owl-item.active.center').index();
+ }
+ //console.log("Get Translate Event::>" + idx);
+ $('.main .mm .slider .owl-item.focus').addClass('unfocus');
+ $('.main .mm .slider .owl-item.focus').removeClass('focus');
+ $('.main .mm .slider .owl-item').eq(idx).addClass('focus');
+ $('.main .mm .slider .owl-item').eq(idx).removeClass('unfocus');
+ });
+ }
+
+ /// 초기화 루틴
+
+ //// 공개 API
+ return {
+ Init: function(width, height) {
+ //ADD Media related event haldner
+ document.addEventListener("media_event_received", __uifxn_AppFull_OnMediaEvt, false);
+ //ADD Key(remote control) event handler
+ document.addEventListener("keydown", __uifxn_AppFull_OnKeyDnEvtRec, false);
+ //ADD Network related event handler
+ document.addEventListener("network_event_received", __uifxn_AppFull_OnNetEvt, false);
+ //ADD Event for the focus change of HCAP application
+ document.addEventListener("hcap_application_focus_changed", __uifxn_AppFull_OnAppFocusEvt, false);
+ //ADD Event for the result of HDMI connection change
+ document.addEventListener("hdmi_connection_changed", __uifxn_AppFull_OnHdmiConChangeEvt, false);
+ },
+
+ Show: function() {
+ let _ctzWc = HotelTV.welcome;
+ let _ctzGst = HotelTV.guestinfo;
+ let _ctzHotel = HotelTV.hotelinfo;
+
+ console.log("Preparing APP[FULL] Page");
+ __uifxn_AppFull_BldPage_Main();
+ },
+
+ MqttEvent: function(_evt) {
+ let _state = HotelTV.state;
+
+ console.log("MQTT RECEVED MESSAGE::> " + _evt);
+ if (_evt == "EVENT-MESSAGE-UPDATE" || _evt == "EVENT-MESSAGE-UPDATE") {
+ //DO NEW GUEST MESSAGE&DO CHANGE GUEST MESSAGE
+ HotelTV.api.GetMessage().then(_ret => {
+ HotelTV.message = _ret;
+ console.log("Get New Message contents");
+ if (_state.menu.stage == "popup_message_card" || _state.menu.stage == "mypage") {
+ let _el_tbls = $('div#lst_mypagebg div #mp_message_table #mp_msg_tblrec');
+ let _msg = HotelTV.message;
+ let _msg_unread_cnt = 0;
+ //기존 메시지 테이블 레코드 삭제
+ _el_tbls.children('tbody').remove();
+ _el_tbls.each(function(_idx, _item) {
+ let _sz_innerHTML = '';
+ let _num_msgIdx = 0;
+ for (let _j = _msg.length; _j > 0; _j--) {
+ _sz_innerHTML += '';
+ if (_msg[_j].read == false) {
+ _sz_innerHTML += '| ' + _j.toString() + ' | ';
+ } else {
+ _sz_innerHTML += '' + _j.toString() + ' | ';
+ }
+
+ if (_msg[_j].multilanguage == false) {
+ _sz_innerHTML += '' + _msg[_j].title.default+' | ';
+ } else {
+ _sz_innerHTML += '' + _msg[_j].title[_state.lang] + ' | ';
+ }
+ _sz_innerHTML += '' + _msg[_j].from + ' | ';
+ _sz_innerHTML += '' + _msg[_j].createdAt + ' | ';
+ _sz_innerHTML += '
';
+ _num_msgIdx++;
+ }
+ _sz_innerHTML += '';
+ $(_item).html(_sz_innerHTML);
+ });
+
+ const _mmIdx = _state.menu.main.cur;
+ // 메시지 상태 오브젝트 초기화
+ if ("message" in _state.menu.main[_mmIdx]) {
+ _state.menu.main[_mmIdx]['message'] = {
+ 'cnt': _msg.length,
+ 'cur': 0,
+ 'prev': null,
+ };
+ }
+ $('.main>.mypage>.bg>.owl-carousel .owl-item #mp_msg_tblrec tr').removeClass('focus');
+ $('.main>.mypage>.bg>.owl-carousel .owl-item #mp_msg_tblrec tr').filter("[msgidx='" + _state.menu.main[_mmIdx]['message']['cur'] + "']").addClass('focus');
+
+ //메시지 개수 표시
+ const _guest = HotelTV.guestinfo;
+ let _trTbl = HotelTV.translation;
+ for (let _j = _msg.length; _j > 0; _j--) {
+ if (_msg[_j].read == false) {
+ _msg_unread_cnt++;
+ }
+ }
+ $('div#lst_mypagebg div #mp_message_title').text(_guest.name + _trTbl.ui.mypage.message.title.title[_state.lang].replace("_XX", _msg_unread_cnt.toString()));
+ }
+ }).catch(_error => {
+ console.log("Fail to get Message info");
+ });
+ } else if (_evt == "EVENT-MESSAGE-DELETE") {
+
+ } else if (_evt == "EVENT-NEWS-UPDATE") {
+ //DO NEW NEWS
+ HotelTV.api.GetNews().then(_ret => {
+ HotelTV.news = _ret;
+ console.log("Get New News contents");
+ __uifxn_AppFull_BldNews();
+ }).catch(_error => {
+ console.log("Fail to get news info");
+ });
+ } else if (_evt == "EVENT-EMERGENCY-START") {
+
+ } else if (_evt == "EVENT-EMERGENCY-STOT") {
+
+ } else if (_evt == "COMMAND-SYSTEM-RESTART") {
+
+ } else if (_evt == "GUEST-CHECKIN") {
+
+ } else if (_evt == "GUEST-CHECKOUT") {
+
+ } else if (_evt == "GUEST-UPDATE") {
+
+ } else if (_evt == "GUEST-ROOMCHANGE") {
+
+ }
+
+
+ // if (_evt == "COMMAND-SET-EVENT-REBOOT") {
+ // //DO REBOOT
+ // } else if (_evt == "COMMAND-SET-EVENT-CHECKIN") {
+ // //DO CHECKIN
+ // } else if (_evt == "COMMAND-SET-EVENT-CHECKOUT") {
+ // //DO CHECKOUT
+ // } else if (_evt == "COMMAND-SET-EVENT-NEW-EMERGENCY") {
+ // //긴급 재난 상황 트리거
+ // } else if (_evt == "COMMAND-SET-EVENT-DEL-EMERGENCY") {
+ // //긴급 재난 상황 해제
+ // } else if (_evt == "COMMAND-SET-EVENT-CHECKOUT") {
+ // //DO CHECKOUT
+ // } else if (_evt == "COMMAND-SET-EVENT-NEWS") {
+ // //DO NEW NEWS
+ // HotelTV.api.GetNews().then(_ret => {
+ // HotelTV.news = _ret;
+ // console.log("Get New News contents");
+ // __uifxn_AppFull_BldNews();
+ // }).catch(_error => {
+ // console.log("Fail to get news info");
+ // });
+ // } else if (_evt == "COMMAND-BDOOR-OPMODE-CHANGE") {
+ // //DO CHANGE OPMODE
+ // } else if (_evt == "COMMAND-SET-EVENT-NETSPEED") {
+ // //DO CHECK NET SPEED
+ // } else if (_evt == "COMMAND-SET-EVENT-SHOWID") {
+ // //DO SHOW DEVICE ID&INFO
+ // } else if (_evt == "COMMAND-SET-EVENT-NEW-MESSAGE" || _evt == "COMMAND-SET-EVENT-CHG-MESSAGE" || _evt == "COMMAND-SET-EVENT-DEL-MESSAGE") {
+ // //DO NEW GUEST MESSAGE&DO CHANGE GUEST MESSAGE
+ // HotelTV.api.GetMessage().then(_ret => {
+ // HotelTV.message = _ret;
+ // console.log("Get New Message contents");
+ // if (_state.menu.stage == "popup_message_card" || _state.menu.stage == "mypage") {
+ // let _el_tbls = $('div#lst_mypagebg div #mp_message_table #mp_msg_tblrec');
+ // let _msg = HotelTV.message;
+ // let _msg_unread_cnt = 0;
+ // //기존 메시지 테이블 레코드 삭제
+ // _el_tbls.children('tbody').remove();
+ // _el_tbls.each(function(_idx, _item) {
+ // let _sz_innerHTML = '';
+ // let _num_msgIdx = 0;
+ // for (let _j = Object.keys(_msg).length - 1; _j >= 0; _j--) {
+ // let _msgId = Object.keys(_msg)[_j];
+ // _sz_innerHTML += '';
+ // if (_msg[_msgId].unread == '1') {
+ // _sz_innerHTML += '| ' + _msgId.toString() + ' | ';
+ // } else {
+ // _sz_innerHTML += '' + _msgId.toString() + ' | ';
+ // }
+ // _sz_innerHTML += '' + _msg[_msgId].name + ' | ';
+ // _sz_innerHTML += '' + _msg[_msgId].writer + ' | ';
+ // _sz_innerHTML += '' + _msg[_msgId].create_at + ' | ';
+ // _sz_innerHTML += '
';
+ // _num_msgIdx++;
+ // }
+ // _sz_innerHTML += '';
+ // $(_item).html(_sz_innerHTML);
+ // });
+
+ // const _mmIdx = _state.menu.main.cur;
+ // let __curMsgDspIdx = 0;
+ // // 메시지 포커싱
+ // if ('message' in Object.keys(_state.menu.main[_mmIdx])) {
+ // _state.menu.main[_mmIdx]['message'] = {
+ // "cnt": Object.keys(_msg).length,
+ // "cur": __curMsgDspIdx,
+ // "prev": null,
+ // };
+ // }
+ // $('.main>.mypage>.bg>.owl-carousel .owl-item #mp_msg_tblrec tr').removeClass('focus');
+ // $('.main>.mypage>.bg>.owl-carousel .owl-item #mp_msg_tblrec tr').filter("[msgidx='" + __curMsgDspIdx + "']").addClass('focus');
+
+ // //메시지 개수 표시
+ // const _guest = HotelTV.guestinfo;
+ // for (let _j in _msg) {
+ // if (_msg[_j].unread == "1") {
+ // _msg_unread_cnt++;
+ // }
+ // }
+ // $('div#lst_mypagebg div #mp_message_title').text(_guest.name + HotelTV.ui_utils.Get_String('message_title', _state.lang).replace("_XX", _msg_unread_cnt.toString()));
+ // }
+ // }).catch(_error => {
+ // console.log("Fail to get Message info");
+ // });
+ // }
+ },
+
+ UpdateEpg: function() {
+ let _state = HotelTV.state;
+
+ if (_state.menu.stage != 'tvCtgHide') {
+ return;
+ }
+
+ let _el_tvctglst = $('.main .tv .bg .owl-item>.item');
+ if (_el_tvctglst.length > 0) {
+ _el_tvctglst.each(function(_idx, _item) {
+ let _el_epg_items = $(_item[_idx]).find('span#tvch_epg_info')
+ _el_epg_items.each(function(_j, _ch) {
+ let _epg_id = _ch.attr('epg_id');
+ let _epg_inf = __uifxn_AppFull_GetEpgInfoById(_epg_id);
+ if (_epg_inf != null) {
+ _ch.text(_egp_prog_inf.name);
+ } else {
+ _ch.text(HotelTV.ui_utils.Get_String('epg_none', _state.lang));
+ }
+ });
+ });
+ }
+ },
+
+ Close: function() {
+ SpatialNavigation.clear();
+ },
+ }
+})();
\ No newline at end of file
diff --git a/procentric/application/lib/hoteltv.ui_utils.js b/procentric/application/lib/hoteltv.ui_utils.js
new file mode 100755
index 0000000..4c4f46b
--- /dev/null
+++ b/procentric/application/lib/hoteltv.ui_utils.js
@@ -0,0 +1,187 @@
+/**
+ * Copyright (c) 2020
+ *
+ * CENTIRM HotelTV UI-UTILS module javascript.
+ *
+ * @summary short description for the file
+ * @author Joel
+ *
+ * Created at : 2020-11-26 02:21:56
+ * Last modified : 2020-11-26 15:31:40
+ */
+
+HotelTV.namespace('HotelTV.ui_utils');
+HotelTV.ui_utils = (function() {
+ //// 의존 관계 선언
+
+ //// 비공개 프로퍼티
+ let g_uiTbl_imgPath_Brochure_buttons = {
+ 'ko-KR': "./images/brochure/bt_brochure_ko.png",
+ 'en-US': "./images/brochure/bt_brochure_en.png",
+ 'zh-CN': "./images/brochure/bt_brochure_ch01.png",
+ 'zh-TW': "./images/brochure/bt_brochure_ch02.png",
+ 'ja-JP': "./images/brochure/bt_brochure_jp.png"
+ };
+
+ let g_uiTbl_imgPath_InRoomDining_buttons = {
+ 'ko-KR': "./images/IRD/bt_inroom_ko.png",
+ 'en-US': "./images/IRD/bt_inroom_en.png",
+ 'zh-CN': "./images/IRD/bt_inroom_ch01.png",
+ 'zh-TW': "./images/IRD/bt_inroom_ch02.png",
+ 'ja-JP': "./images/IRD/bt_inroom_jp.png"
+ };
+
+ let g_uiTbl_String = {
+ // //Words & Sentance for Menu & Contents
+
+
+
+ // 'guide_flightschedule': {
+ // 'kr': '화살표를 사용하여 제주국제공항 출발, 도착하는 항공 스케줄을 확인하세요.',
+ // 'en': 'Use the arrows to check flight schedules arriving and leaving from Jeju International Airport.',
+ // 'ch': '请用箭头查看济州国际机场出发、到达航班的时刻表。',
+ // 'tw': '請用箭頭查看濟州國際機場出發、到達航班的時刻表。',
+ // 'jp': '矢印を使って済州国際空港出発便、到着便の航空スケジュールをご確認ください。'
+ // },
+
+ // //EPG
+ // 'epg_none': {
+ // 'kr': "프로그램 정보가 없습니다",
+ // 'en': "No program information",
+ // 'ch': "没有节目信息",
+ // 'tw': "沒有節目信息",
+ // 'jp': "プログラム情報はありません"
+ // },
+ };
+
+ var g_uiVar_Clock = {
+ time: '',
+ date: ''
+ };
+
+
+ /// 초기화 루틴
+
+
+
+
+
+ //// 비공개 매써드
+ /**
+ * HotelTV UI Wrapper Function::> Show(Build) Busy(loading) animation
+ * @param {boolean} enable enable/disable
+ */
+ function __uiFxn_MiscZeroPadding(num, digit) {
+ var zero = '';
+ for (var i = 0; i < digit; i++) {
+ zero += '0';
+ }
+ return (zero + num).slice(-digit);
+ }
+
+ /**
+ * HotelTV UI Wrapper Function::> Show(Build) Busy(loading) animation
+ * @param {boolean} enable enable/disable
+ */
+ function __uifxn_BusyAnimation(enable) {
+ if (enable) {
+ //$('#busy_animation').css("background-image", "url('./images/icons/icon_loading_256x256')");
+ $('.busy-frame').fadeIn(200, function() {
+ $('.busy-frame #busy_animation').show();
+ });
+ } else {
+ $('.busy-frame #busy_animation').fadeOut(300, function() {
+ $('.busy-frame').fadeOut(500);
+ });
+ }
+ }
+
+
+ //// 공개 API
+ return {
+ SetBusy: function(show) {
+ __uifxn_BusyAnimation(show);
+ },
+
+ ShowErrMsg: function(_show, _title, _msg) {
+ if (_show) {
+ $('.error').css("background-color", "rgb(255,0,0)");
+ $('.error').fadeIn(500);
+ } else {
+ $('.error').fadeOut(500, function() {
+ $(this).css("background-image", "None");
+ });
+ }
+ },
+
+ GetCur_DateTime: function() {
+ let week = ['SUN', 'MON', 'TUE', 'WED', 'THU', 'FRI', 'SAT'];
+ let cd = new Date();
+ g_uiVar_Clock.time = __uiFxn_MiscZeroPadding(cd.getHours(), 2) + ':' + __uiFxn_MiscZeroPadding(cd.getMinutes(), 2) + ':' + __uiFxn_MiscZeroPadding(cd.getSeconds(), 2);
+ g_uiVar_Clock.date = __uiFxn_MiscZeroPadding(cd.getFullYear(), 4) + '-' + __uiFxn_MiscZeroPadding(cd.getMonth() + 1, 2) + '-' + __uiFxn_MiscZeroPadding(cd.getDate(), 2) + ' ' + week[cd.getDay()];
+ return g_uiVar_Clock;
+ },
+
+ Get_String: function(_key, _lang) {
+ return g_uiTbl_String[_key][_lang];
+ },
+
+ Brochure_GetBtn: function(_lang) {
+ return g_uiTbl_imgPath_Brochure_buttons[_lang];
+ },
+
+ IRD_GetBtn: function(_lang) {
+ return g_uiTbl_imgPath_InRoomDining_buttons[_lang];
+ },
+
+ Get_Airline: function(_obj, _airline, _lang) {
+ if (_obj) {
+ if (_obj[_airline]) {
+ return _obj[_airline][_lang] || _airline;
+ }
+ }
+ return _airline;
+ },
+
+ Get_Airport: function(_obj, _airport, _lang) {
+ if (_obj) {
+ if (_obj[_airport]) {
+ return _obj[_airport][_lang] || _airport;
+ }
+ }
+ return _airport;
+ },
+
+ Get_FlightStatus: function(_obj, _status, _lang) {
+ if (_obj) {
+ if (_status && _status != "") {
+ return _obj[_status][_lang] || _status;
+ }
+ }
+ return _status;
+ },
+
+ Weather_GetWindReport: function(_str, _speed, _direction, _lang) {
+ let _cvt_speed = parseFloat((_speed * 1000 / 3600)).toFixed(2);
+ let _szDir = null;
+ if (_direction >= 345 && _direction < 22) {
+ _szDir = _str[4][_lang];
+ } else if (_direction >= 23 && _direction < 68) {
+ _szDir = _str[14][_lang];
+ } else if (_direction >= 69 && _direction < 114) {
+ _szDir = _str[1][_lang];
+ } else if (_direction >= 115 && _direction < 160) {
+ _szDir = _str[13][_lang];
+ } else if (_direction >= 161 && _direction < 206) {
+ _szDir = _str[3][_lang];
+ } else if (_direction >= 207 && _direction < 252) {
+ _szDir = _str[12][_lang];
+ } else if (_direction >= 253 && _direction < 298) {
+ _szDir = _str[2][_lang];
+ } else {
+ _szDir = _str[15][_lang];
+ }
+ return _cvt_speed.toString() + " " + _szDir;
+ },
+ }
+})();
\ No newline at end of file
diff --git a/procentric/application/lib/hoteltv.ui_welcome.js b/procentric/application/lib/hoteltv.ui_welcome.js
new file mode 100755
index 0000000..78ccf41
--- /dev/null
+++ b/procentric/application/lib/hoteltv.ui_welcome.js
@@ -0,0 +1,396 @@
+/**
+ * Copyright (c) 2020
+ *
+ * CENTIRM HotelTV UI-WELCOME module javascript.
+ *
+ * @summary short description for the file
+ * @author Joel
+ *
+ * Created at : 2020-11-26 02:21:56
+ * Last modified : 2020-11-26 15:31:40
+ */
+
+HotelTV.namespace('HotelTV.ui_welcome');
+HotelTV.ui_welcome = (function() {
+ //// 의존 관계 선언
+ let hndl_langSel = null;
+ let _media_status = null;
+
+ //// 비공개 프로퍼티
+
+ /// 초기화 루틴
+ /**
+ * HotelTV UI Wrapper Function::> received event handling function
+ * @param {boolean} e event
+ */
+ function __uifxn_WC_OnMediaEvt(e) {
+ let _state = HotelTV.state;
+ console.log("media_event_received = " + e.eventType);
+ let _stateMedia = e.eventType;
+ switch (_stateMedia) {
+ case 'play_start':
+ _media_status = 'playing';
+ HotelTV.hcap.VideoWinSize(null);
+
+ //Hide welcome page
+ __uifxn_WC_Show(null, function() {
+ _state.menu.stage = "playWelcomeMovie";
+
+ $('#lst_langsel').off('changed.owl.carousel');
+ $('#lst_langsel').owlCarousel('destroy');
+ $('.welcome #lst_langsel div').remove();
+
+ if ($(".control .skip_video").css('display') == 'none') {
+ $(".control .skip_video").fadeIn(1000);
+ setTimeout(() => {
+ $(".control .skip_video").fadeOut(1000);
+ }, 3000);
+ }
+ });
+ break;
+ case 'play_end':
+ _media_status = 'stopped';
+ HotelTV.hcap.MediaShutdown(
+ function() {
+ $(".control .skip_video").hide();
+ console.log("Media Desory::Done");
+ HotelTV.UnloadWelCome();
+ },
+ function() {
+ console.log("Media Desory::Fail");
+ $(".control .skip_video").hide();
+ HotelTV.UnloadWelCome();
+ });
+ break;
+ case 'play_end_need_destory':
+ HotelTV.hcap.MediaShutdown(
+ function() {
+ $(".control .skip_video").hide();
+ console.log("Media Desory::Done");
+ HotelTV.UnloadWelCome();
+ },
+ function() {
+ console.log("Media Desory::Fail");
+ $(".control .skip_video").hide();
+ HotelTV.UnloadWelCome();
+ });
+ break;
+ case 'error_in_playing':
+ break;
+ case 'buffer_full':
+ break;
+ case 'file_not_found':
+ break;
+ case 'network_disconnected':
+ break;
+ case 'network_busy':
+ break;
+ case 'seek_done':
+ break;
+
+ case 'play_stop_requtested':
+ _media_status = 'stopped';
+ HotelTV.hcap.MediaShutdown(
+ function() {
+ $(".control .skip_video").hide();
+ console.log("Media Desory::Done");
+ HotelTV.UnloadWelCome();
+ },
+ function() {
+ console.log("Media Desory::Fail");
+ $(".control .skip_video").hide();
+ HotelTV.UnloadWelCome();
+ });
+ break;
+ }
+ }
+
+ /**
+ * HotelTV UI Wrapper Function::> received event handling function
+ * @param {dictionary} _evt event information
+ */
+ function __uifxn_WC_OnNetEvt(_evt) {
+ let _state = HotelTV.state;
+ console.log("network_event_received = " + _evt.eventType);
+ let _typeNetEvt = _evt.eventType;
+
+ switch (_typeNetEvt) {
+ case hcap.network.NetworkEventType.ABLE_REACH_DNS:
+ break;
+ case hcap.network.NetworkEventType.ABLE_REACH_GATEWAY:
+ break;
+ case hcap.network.NetworkEventType.ABLE_REACH_INTERNET:
+ break;
+ case hcap.network.NetworkEventType.DHCP_FAIL:
+ break;
+ case hcap.network.NetworkEventType.DHCP_SUCCESS:
+ break;
+ case hcap.network.NetworkEventType.ETHERNET_PLUGGED:
+ break;
+ case hcap.network.NetworkEventType.ETHERNET_UNPLUGGED:
+ break;
+ case hcap.network.NetworkEventType.IP_CONFLICT:
+ break;
+ case hcap.network.NetworkEventType.IP_NOT_CONFLICT:
+ break;
+ case hcap.network.NetworkEventType.UNABLE_REACH_DNS:
+ break;
+ case hcap.network.NetworkEventType.UNABLE_REACH_GATEWAY:
+ break;
+ case hcap.network.NetworkEventType.UNABLE_REACH_INTERNET:
+ break;
+ case hcap.network.NetworkEventType.UNKNOWN:
+ break;
+ case hcap.network.NetworkEventType.WIFI_AP_SEARCH_COMPLETE:
+ break;
+ case hcap.network.NetworkEventType.WIFI_CONNECT_FAIL:
+ break;
+ case hcap.network.NetworkEventType.WIFI_CONNECTED:
+ break;
+ case hcap.network.NetworkEventType.WIFI_DONGLE_PLUGGED:
+ break;
+ case hcap.network.NetworkEventType.WIFI_DONGLE_UNPLUGGED:
+ break;
+ case hcap.network.NetworkEventType.WIFI_LINK_DROPPED:
+ break;
+ }
+ }
+
+ /**
+ * HotelTV UI Wrapper Function::> Show Welcome Hotel Logo
+ * @param {boolean} uri_img background image url
+ */
+ function __uifxn_WC_SetHotelLogo(uri_img) {
+ let _elmnt_img_hotellogo = $(".welcome > .frame > .msgwin #hotellogo");
+ if (uri_img != null) {
+ _elmnt_img_hotellogo.css({
+ "background-image": "url(" + uri_img + ")",
+ "background-size": "100% 100%"
+ });
+ } else {
+ _elmnt_img_hotellogo.css({ "background": "none" });
+ }
+ }
+
+ /**
+ * HotelTV UI Wrapper Function::> Fillup welcome contents
+ * @param {boolean} sz_name Guest Name
+ * * @param {boolean} sz_msg Greeting Message
+ */
+ function __uifxn_WC_SetCtz(sz_name, sz_msg) {
+ let _state = HotelTV.state;
+ let _trTbl = HotelTV.translation;
+ let _elmnt_guest_name = $(".welcome > .frame > .msgwin #guestname");
+ let _elmnt_welcomemsg = $(".welcome > .frame > .msgwin #welcomemsg");
+ let _elmnt_img_guide = $(".welcome > .frame > .guide#langsel");
+
+ if (sz_name != null) {
+ _elmnt_guest_name.html(sz_name + '
');
+ } else {
+ _elmnt_guest_name.html('
');
+ }
+
+ if (sz_msg[_state.lang] != null) {
+ _elmnt_welcomemsg.html(sz_msg[_state.lang] + '
');
+ } else {
+ _elmnt_welcomemsg.html('
');
+ }
+ _elmnt_img_guide.text(_trTbl.ui.welcome.guide_wc_langsel[_state.lang]);
+ }
+
+ /**
+ * HotelTV UI Wrapper Function::> build welcome Main UI
+ * @param {boolean} uri_img background image url
+ */
+ function __uifxn_WC_BldPage() {
+ let _ctzOpening = HotelTV.opening;
+ let _ctzWc = _ctzOpening.welcome;
+ let _state = HotelTV.state;
+
+
+ //Supported Language Count
+ let _langCnt = Object.keys(_ctzOpening.languages).length;
+ let _SupportedLang = _ctzOpening.languages;
+
+ //Add html elements for language selection
+ let _div_langsel = document.querySelector('.welcome #lst_langsel');
+ for (let __lang in _SupportedLang) {
+ let _div_lang_btn = document.createElement('div');
+ let _sz_styleOpt = null;
+
+ _div_lang_btn.className = 'item';
+ _div_lang_btn.id = 'wc_eit_langsel_' + __lang;
+ _div_lang_btn.textContent = _SupportedLang[__lang].name;
+ _div_lang_btn.setAttribute("lang", __lang);
+ _sz_styleOpt = "--btn_focus:url(./images/bt_language_tab_focus.png); --btn_unfocus:url(./images/bt_language_tab_unfocus.png);";
+ _div_lang_btn.setAttribute("style", _sz_styleOpt);
+ _div_langsel.appendChild(_div_lang_btn);
+ }
+
+ //
+ let _start_pos = 0;
+ for (let __lang in _SupportedLang) {
+ if (_state.lang == __lang) {
+ break;
+ }
+ _start_pos++;
+ }
+ hndl_langSel = $('#lst_langsel');
+ hndl_langSel.owlCarousel({
+ center: true,
+ items: Number(_langCnt - 1), //Number of Items on Screen what you want
+ loop: true,
+ margin: 0,
+ smartSpeed: 700,
+ autoWidth: false,
+ mouseDrag: false,
+ touchDrag: false,
+ pullDrag: false,
+ freeDrag: false,
+ startPosition: _start_pos,
+ });
+ }
+
+ /**
+ * HotelTV UI Wrapper Function::> show welcome Main UI
+ * @param {boolean} uri_img background image url
+ */
+ function __uifxn_WC_Show(uri_img, _callback) {
+ if (uri_img != null) {
+ //Decision fist displyed language
+ let _state = HotelTV.state;
+ let _ctzOpening = HotelTV.opening;
+ let _ctzWc = _ctzOpening.welcome;
+ let _ctzGst = HotelTV.guestinfo;
+ let _ctzHotel = HotelTV.hotelinfo;
+
+ hndl_langSel = $('#lst_langsel');
+ $(".welcome").show();
+ $(".welcome > .frame").css("background-image", "url(" + uri_img + ")");
+ $(".welcome > .frame").fadeIn(500, function() {
+ hndl_langSel.show();
+ //배경 출력후 1.5초 뒤에 호텔 로그와 웰컴 메시지 출력하도록 타임아웃 적용
+ setTimeout(function() {
+ __uifxn_WC_SetHotelLogo(_ctzHotel.mainLogo.download);
+ setTimeout(function() {
+ $('.welcome .frame .msgwin #welcomemsg').fadeIn(500, function() {
+ $('.welcome .frame .msgwin #guestname').fadeIn(500, function() {
+ _state.menu.stage = "langSel"
+ });
+ });
+ }, 500);
+ }, 500);
+ });
+
+
+
+ $(document).on('keydown', function(_evt) { //attach event listener
+ console.log("LANGSEL KEY EVENT::> " + _evt.keyCode);
+ if (_state.menu.stage == "langSel") {
+ if (_evt.keyCode == 37) {
+ $('#lst_langsel').trigger('prev.owl')
+ } else if (_evt.keyCode == 39) {
+ $('#lst_langsel').trigger('next.owl')
+ } else if (_evt.keyCode == 13) {
+ // SET PLATFORM LANGUAGE
+ // HotelTV.hcap.SetPlatformLanguage(_state.lang);
+
+ // LANGUAGE 선택
+ if (_ctzWc.intro == 'image') {
+ /** Play slide shows */
+
+ } else if (_ctzWc.intro == 'video') {
+
+ /** Play movie clip */
+ HotelTV.hcap.MediaPlay(
+ HotelTV.api.GetBaseUrl() + _ctzWc.videos[_state.lang].download,
+ null,
+ "video/mp4",
+ 1,
+ () => {
+ console.log("STARTUP Done CB.");
+ //Shows up skip button
+ let _elmnt_btn_skip = $(".control .skip_video");
+ _elmnt_btn_skip.css({
+ "background-image": "url(" + "./images/bt_skip_en.png" + ")",
+ "background-size": "100% 100%"
+ });
+ },
+ () => {
+ console.log("STARTUP Fail CB.");
+ HotelTV.UnloadWelCome();
+ }
+ );
+ } else {
+ console.log("No welcome post contents");
+ }
+ }
+ } else if (_state.menu.stage == "playWelcomeMovie") {
+ if (_evt.keyCode == 413) {
+ // STOP KEY Event
+ if (_media_status == 'playing') {
+ _media_status = 'preparing_stop_playing';
+ var _evt = new Event('media_event_received');
+ _evt.eventType = "play_end_need_destory";
+ _evt.command_id = "event";
+ document.dispatchEvent(_evt);
+ }
+ } else {
+ console.log(">>");
+ if (_media_status == 'playing') {
+ if ($(".control .skip_video").css('display') == 'none') {
+ $(".control .skip_video").fadeIn(1000);
+ setTimeout(() => {
+ $(".control .skip_video").fadeOut(1000);
+ }, 3000);
+ } else {
+ const _evt = new Event('media_event_received');
+ _evt['command_id'] = "media_event_received";
+ _evt['eventType'] = "play_stop_requtested";
+ document.dispatchEvent(_evt);
+ }
+ }
+ }
+ }
+ });
+
+
+
+ hndl_langSel.on('changed.owl.carousel', function(event) {
+ // Update Language
+ console.log("LANG SEL[CHANGED]::>" + event.page.index);
+ _state.lang = Object.keys(_ctzOpening.languages)[event.page.index];
+ __uifxn_WC_SetCtz(_ctzGst.name, _ctzWc.message);
+ });
+ } else {
+ //Hide welcome main frame
+ if (_callback != null) {
+ $(".welcome").fadeOut(1000, _callback); // display 속성을 none 으로 바꾼다.
+ } else {
+ $(".welcome").fadeOut(1000); // display 속성을 none 으로 바꾼다.
+ }
+ }
+ }
+
+ //// 공개 API
+ return {
+ Init: function(width, height) {
+ //ADD Media related event handler
+ document.addEventListener("media_event_received", __uifxn_WC_OnMediaEvt, false);
+ //ADD Network related event handler
+ document.addEventListener("network_event_received", __uifxn_WC_OnNetEvt, false);
+
+ // Build up Welcome Page
+ __uifxn_WC_BldPage();
+ },
+
+ Show: function() {
+ let _ctzWc = HotelTV.opening.welcome;
+ __uifxn_WC_Show(_ctzWc.background.file.download, null);
+ },
+
+ Close: function() {
+ SpatialNavigation.clear();
+ },
+ }
+})();
\ No newline at end of file
diff --git a/procentric/application/lib/jquery-2.2.4.js b/procentric/application/lib/jquery-2.2.4.js
new file mode 100755
index 0000000..5c3c456
--- /dev/null
+++ b/procentric/application/lib/jquery-2.2.4.js
@@ -0,0 +1,9814 @@
+/*!
+ * jQuery JavaScript Library v2.2.4
+ * http://jquery.com/
+ *
+ * Includes Sizzle.js
+ * http://sizzlejs.com/
+ *
+ * Copyright jQuery Foundation and other contributors
+ * Released under the MIT license
+ * http://jquery.org/license
+ *
+ * Date: 2016-05-20T17:23Z
+ */
+
+(function( global, factory ) {
+
+ if ( typeof module === "object" && typeof module.exports === "object" ) {
+ // For CommonJS and CommonJS-like environments where a proper `window`
+ // is present, execute the factory and get jQuery.
+ // For environments that do not have a `window` with a `document`
+ // (such as Node.js), expose a factory as module.exports.
+ // This accentuates the need for the creation of a real `window`.
+ // e.g. var jQuery = require("jquery")(window);
+ // See ticket #14549 for more info.
+ module.exports = global.document ?
+ factory( global, true ) :
+ function( w ) {
+ if ( !w.document ) {
+ throw new Error( "jQuery requires a window with a document" );
+ }
+ return factory( w );
+ };
+ } else {
+ factory( global );
+ }
+
+// Pass this if window is not defined yet
+}(typeof window !== "undefined" ? window : this, function( window, noGlobal ) {
+
+// Support: Firefox 18+
+// Can't be in strict mode, several libs including ASP.NET trace
+// the stack via arguments.caller.callee and Firefox dies if
+// you try to trace through "use strict" call chains. (#13335)
+//"use strict";
+var arr = [];
+
+var document = window.document;
+
+var slice = arr.slice;
+
+var concat = arr.concat;
+
+var push = arr.push;
+
+var indexOf = arr.indexOf;
+
+var class2type = {};
+
+var toString = class2type.toString;
+
+var hasOwn = class2type.hasOwnProperty;
+
+var support = {};
+
+
+
+var
+ version = "2.2.4",
+
+ // Define a local copy of jQuery
+ jQuery = function( selector, context ) {
+
+ // The jQuery object is actually just the init constructor 'enhanced'
+ // Need init if jQuery is called (just allow error to be thrown if not included)
+ return new jQuery.fn.init( selector, context );
+ },
+
+ // Support: Android<4.1
+ // Make sure we trim BOM and NBSP
+ rtrim = /^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g,
+
+ // Matches dashed string for camelizing
+ rmsPrefix = /^-ms-/,
+ rdashAlpha = /-([\da-z])/gi,
+
+ // Used by jQuery.camelCase as callback to replace()
+ fcamelCase = function( all, letter ) {
+ return letter.toUpperCase();
+ };
+
+jQuery.fn = jQuery.prototype = {
+
+ // The current version of jQuery being used
+ jquery: version,
+
+ constructor: jQuery,
+
+ // Start with an empty selector
+ selector: "",
+
+ // The default length of a jQuery object is 0
+ length: 0,
+
+ toArray: function() {
+ return slice.call( this );
+ },
+
+ // Get the Nth element in the matched element set OR
+ // Get the whole matched element set as a clean array
+ get: function( num ) {
+ return num != null ?
+
+ // Return just the one element from the set
+ ( num < 0 ? this[ num + this.length ] : this[ num ] ) :
+
+ // Return all the elements in a clean array
+ slice.call( this );
+ },
+
+ // Take an array of elements and push it onto the stack
+ // (returning the new matched element set)
+ pushStack: function( elems ) {
+
+ // Build a new jQuery matched element set
+ var ret = jQuery.merge( this.constructor(), elems );
+
+ // Add the old object onto the stack (as a reference)
+ ret.prevObject = this;
+ ret.context = this.context;
+
+ // Return the newly-formed element set
+ return ret;
+ },
+
+ // Execute a callback for every element in the matched set.
+ each: function( callback ) {
+ return jQuery.each( this, callback );
+ },
+
+ map: function( callback ) {
+ return this.pushStack( jQuery.map( this, function( elem, i ) {
+ return callback.call( elem, i, elem );
+ } ) );
+ },
+
+ slice: function() {
+ return this.pushStack( slice.apply( this, arguments ) );
+ },
+
+ first: function() {
+ return this.eq( 0 );
+ },
+
+ last: function() {
+ return this.eq( -1 );
+ },
+
+ eq: function( i ) {
+ var len = this.length,
+ j = +i + ( i < 0 ? len : 0 );
+ return this.pushStack( j >= 0 && j < len ? [ this[ j ] ] : [] );
+ },
+
+ end: function() {
+ return this.prevObject || this.constructor();
+ },
+
+ // For internal use only.
+ // Behaves like an Array's method, not like a jQuery method.
+ push: push,
+ sort: arr.sort,
+ splice: arr.splice
+};
+
+jQuery.extend = jQuery.fn.extend = function() {
+ var options, name, src, copy, copyIsArray, clone,
+ target = arguments[ 0 ] || {},
+ i = 1,
+ length = arguments.length,
+ deep = false;
+
+ // Handle a deep copy situation
+ if ( typeof target === "boolean" ) {
+ deep = target;
+
+ // Skip the boolean and the target
+ target = arguments[ i ] || {};
+ i++;
+ }
+
+ // Handle case when target is a string or something (possible in deep copy)
+ if ( typeof target !== "object" && !jQuery.isFunction( target ) ) {
+ target = {};
+ }
+
+ // Extend jQuery itself if only one argument is passed
+ if ( i === length ) {
+ target = this;
+ i--;
+ }
+
+ for ( ; i < length; i++ ) {
+
+ // Only deal with non-null/undefined values
+ if ( ( options = arguments[ i ] ) != null ) {
+
+ // Extend the base object
+ for ( name in options ) {
+ src = target[ name ];
+ copy = options[ name ];
+
+ // Prevent never-ending loop
+ if ( target === copy ) {
+ continue;
+ }
+
+ // Recurse if we're merging plain objects or arrays
+ if ( deep && copy && ( jQuery.isPlainObject( copy ) ||
+ ( copyIsArray = jQuery.isArray( copy ) ) ) ) {
+
+ if ( copyIsArray ) {
+ copyIsArray = false;
+ clone = src && jQuery.isArray( src ) ? src : [];
+
+ } else {
+ clone = src && jQuery.isPlainObject( src ) ? src : {};
+ }
+
+ // Never move original objects, clone them
+ target[ name ] = jQuery.extend( deep, clone, copy );
+
+ // Don't bring in undefined values
+ } else if ( copy !== undefined ) {
+ target[ name ] = copy;
+ }
+ }
+ }
+ }
+
+ // Return the modified object
+ return target;
+};
+
+jQuery.extend( {
+
+ // Unique for each copy of jQuery on the page
+ expando: "jQuery" + ( version + Math.random() ).replace( /\D/g, "" ),
+
+ // Assume jQuery is ready without the ready module
+ isReady: true,
+
+ error: function( msg ) {
+ throw new Error( msg );
+ },
+
+ noop: function() {},
+
+ isFunction: function( obj ) {
+ return jQuery.type( obj ) === "function";
+ },
+
+ isArray: Array.isArray,
+
+ isWindow: function( obj ) {
+ return obj != null && obj === obj.window;
+ },
+
+ isNumeric: function( obj ) {
+
+ // parseFloat NaNs numeric-cast false positives (null|true|false|"")
+ // ...but misinterprets leading-number strings, particularly hex literals ("0x...")
+ // subtraction forces infinities to NaN
+ // adding 1 corrects loss of precision from parseFloat (#15100)
+ var realStringObj = obj && obj.toString();
+ return !jQuery.isArray( obj ) && ( realStringObj - parseFloat( realStringObj ) + 1 ) >= 0;
+ },
+
+ isPlainObject: function( obj ) {
+ var key;
+
+ // Not plain objects:
+ // - Any object or value whose internal [[Class]] property is not "[object Object]"
+ // - DOM nodes
+ // - window
+ if ( jQuery.type( obj ) !== "object" || obj.nodeType || jQuery.isWindow( obj ) ) {
+ return false;
+ }
+
+ // Not own constructor property must be Object
+ if ( obj.constructor &&
+ !hasOwn.call( obj, "constructor" ) &&
+ !hasOwn.call( obj.constructor.prototype || {}, "isPrototypeOf" ) ) {
+ return false;
+ }
+
+ // Own properties are enumerated firstly, so to speed up,
+ // if last one is own, then all properties are own
+ for ( key in obj ) {}
+
+ return key === undefined || hasOwn.call( obj, key );
+ },
+
+ isEmptyObject: function( obj ) {
+ var name;
+ for ( name in obj ) {
+ return false;
+ }
+ return true;
+ },
+
+ type: function( obj ) {
+ if ( obj == null ) {
+ return obj + "";
+ }
+
+ // Support: Android<4.0, iOS<6 (functionish RegExp)
+ return typeof obj === "object" || typeof obj === "function" ?
+ class2type[ toString.call( obj ) ] || "object" :
+ typeof obj;
+ },
+
+ // Evaluates a script in a global context
+ globalEval: function( code ) {
+ var script,
+ indirect = eval;
+
+ code = jQuery.trim( code );
+
+ if ( code ) {
+
+ // If the code includes a valid, prologue position
+ // strict mode pragma, execute code by injecting a
+ // script tag into the document.
+ if ( code.indexOf( "use strict" ) === 1 ) {
+ script = document.createElement( "script" );
+ script.text = code;
+ document.head.appendChild( script ).parentNode.removeChild( script );
+ } else {
+
+ // Otherwise, avoid the DOM node creation, insertion
+ // and removal by using an indirect global eval
+
+ indirect( code );
+ }
+ }
+ },
+
+ // Convert dashed to camelCase; used by the css and data modules
+ // Support: IE9-11+
+ // Microsoft forgot to hump their vendor prefix (#9572)
+ camelCase: function( string ) {
+ return string.replace( rmsPrefix, "ms-" ).replace( rdashAlpha, fcamelCase );
+ },
+
+ nodeName: function( elem, name ) {
+ return elem.nodeName && elem.nodeName.toLowerCase() === name.toLowerCase();
+ },
+
+ each: function( obj, callback ) {
+ var length, i = 0;
+
+ if ( isArrayLike( obj ) ) {
+ length = obj.length;
+ for ( ; i < length; i++ ) {
+ if ( callback.call( obj[ i ], i, obj[ i ] ) === false ) {
+ break;
+ }
+ }
+ } else {
+ for ( i in obj ) {
+ if ( callback.call( obj[ i ], i, obj[ i ] ) === false ) {
+ break;
+ }
+ }
+ }
+
+ return obj;
+ },
+
+ // Support: Android<4.1
+ trim: function( text ) {
+ return text == null ?
+ "" :
+ ( text + "" ).replace( rtrim, "" );
+ },
+
+ // results is for internal usage only
+ makeArray: function( arr, results ) {
+ var ret = results || [];
+
+ if ( arr != null ) {
+ if ( isArrayLike( Object( arr ) ) ) {
+ jQuery.merge( ret,
+ typeof arr === "string" ?
+ [ arr ] : arr
+ );
+ } else {
+ push.call( ret, arr );
+ }
+ }
+
+ return ret;
+ },
+
+ inArray: function( elem, arr, i ) {
+ return arr == null ? -1 : indexOf.call( arr, elem, i );
+ },
+
+ merge: function( first, second ) {
+ var len = +second.length,
+ j = 0,
+ i = first.length;
+
+ for ( ; j < len; j++ ) {
+ first[ i++ ] = second[ j ];
+ }
+
+ first.length = i;
+
+ return first;
+ },
+
+ grep: function( elems, callback, invert ) {
+ var callbackInverse,
+ matches = [],
+ i = 0,
+ length = elems.length,
+ callbackExpect = !invert;
+
+ // Go through the array, only saving the items
+ // that pass the validator function
+ for ( ; i < length; i++ ) {
+ callbackInverse = !callback( elems[ i ], i );
+ if ( callbackInverse !== callbackExpect ) {
+ matches.push( elems[ i ] );
+ }
+ }
+
+ return matches;
+ },
+
+ // arg is for internal usage only
+ map: function( elems, callback, arg ) {
+ var length, value,
+ i = 0,
+ ret = [];
+
+ // Go through the array, translating each of the items to their new values
+ if ( isArrayLike( elems ) ) {
+ length = elems.length;
+ for ( ; i < length; i++ ) {
+ value = callback( elems[ i ], i, arg );
+
+ if ( value != null ) {
+ ret.push( value );
+ }
+ }
+
+ // Go through every key on the object,
+ } else {
+ for ( i in elems ) {
+ value = callback( elems[ i ], i, arg );
+
+ if ( value != null ) {
+ ret.push( value );
+ }
+ }
+ }
+
+ // Flatten any nested arrays
+ return concat.apply( [], ret );
+ },
+
+ // A global GUID counter for objects
+ guid: 1,
+
+ // Bind a function to a context, optionally partially applying any
+ // arguments.
+ proxy: function( fn, context ) {
+ var tmp, args, proxy;
+
+ if ( typeof context === "string" ) {
+ tmp = fn[ context ];
+ context = fn;
+ fn = tmp;
+ }
+
+ // Quick check to determine if target is callable, in the spec
+ // this throws a TypeError, but we will just return undefined.
+ if ( !jQuery.isFunction( fn ) ) {
+ return undefined;
+ }
+
+ // Simulated bind
+ args = slice.call( arguments, 2 );
+ proxy = function() {
+ return fn.apply( context || this, args.concat( slice.call( arguments ) ) );
+ };
+
+ // Set the guid of unique handler to the same of original handler, so it can be removed
+ proxy.guid = fn.guid = fn.guid || jQuery.guid++;
+
+ return proxy;
+ },
+
+ now: Date.now,
+
+ // jQuery.support is not used in Core but other projects attach their
+ // properties to it so it needs to exist.
+ support: support
+} );
+
+// JSHint would error on this code due to the Symbol not being defined in ES5.
+// Defining this global in .jshintrc would create a danger of using the global
+// unguarded in another place, it seems safer to just disable JSHint for these
+// three lines.
+/* jshint ignore: start */
+if ( typeof Symbol === "function" ) {
+ jQuery.fn[ Symbol.iterator ] = arr[ Symbol.iterator ];
+}
+/* jshint ignore: end */
+
+// Populate the class2type map
+jQuery.each( "Boolean Number String Function Array Date RegExp Object Error Symbol".split( " " ),
+function( i, name ) {
+ class2type[ "[object " + name + "]" ] = name.toLowerCase();
+} );
+
+function isArrayLike( obj ) {
+
+ // Support: iOS 8.2 (not reproducible in simulator)
+ // `in` check used to prevent JIT error (gh-2145)
+ // hasOwn isn't used here due to false negatives
+ // regarding Nodelist length in IE
+ var length = !!obj && "length" in obj && obj.length,
+ type = jQuery.type( obj );
+
+ if ( type === "function" || jQuery.isWindow( obj ) ) {
+ return false;
+ }
+
+ return type === "array" || length === 0 ||
+ typeof length === "number" && length > 0 && ( length - 1 ) in obj;
+}
+var Sizzle =
+/*!
+ * Sizzle CSS Selector Engine v2.2.1
+ * http://sizzlejs.com/
+ *
+ * Copyright jQuery Foundation and other contributors
+ * Released under the MIT license
+ * http://jquery.org/license
+ *
+ * Date: 2015-10-17
+ */
+(function( window ) {
+
+var i,
+ support,
+ Expr,
+ getText,
+ isXML,
+ tokenize,
+ compile,
+ select,
+ outermostContext,
+ sortInput,
+ hasDuplicate,
+
+ // Local document vars
+ setDocument,
+ document,
+ docElem,
+ documentIsHTML,
+ rbuggyQSA,
+ rbuggyMatches,
+ matches,
+ contains,
+
+ // Instance-specific data
+ expando = "sizzle" + 1 * new Date(),
+ preferredDoc = window.document,
+ dirruns = 0,
+ done = 0,
+ classCache = createCache(),
+ tokenCache = createCache(),
+ compilerCache = createCache(),
+ sortOrder = function( a, b ) {
+ if ( a === b ) {
+ hasDuplicate = true;
+ }
+ return 0;
+ },
+
+ // General-purpose constants
+ MAX_NEGATIVE = 1 << 31,
+
+ // Instance methods
+ hasOwn = ({}).hasOwnProperty,
+ arr = [],
+ pop = arr.pop,
+ push_native = arr.push,
+ push = arr.push,
+ slice = arr.slice,
+ // Use a stripped-down indexOf as it's faster than native
+ // http://jsperf.com/thor-indexof-vs-for/5
+ indexOf = function( list, elem ) {
+ var i = 0,
+ len = list.length;
+ for ( ; i < len; i++ ) {
+ if ( list[i] === elem ) {
+ return i;
+ }
+ }
+ return -1;
+ },
+
+ booleans = "checked|selected|async|autofocus|autoplay|controls|defer|disabled|hidden|ismap|loop|multiple|open|readonly|required|scoped",
+
+ // Regular expressions
+
+ // http://www.w3.org/TR/css3-selectors/#whitespace
+ whitespace = "[\\x20\\t\\r\\n\\f]",
+
+ // http://www.w3.org/TR/CSS21/syndata.html#value-def-identifier
+ identifier = "(?:\\\\.|[\\w-]|[^\\x00-\\xa0])+",
+
+ // Attribute selectors: http://www.w3.org/TR/selectors/#attribute-selectors
+ attributes = "\\[" + whitespace + "*(" + identifier + ")(?:" + whitespace +
+ // Operator (capture 2)
+ "*([*^$|!~]?=)" + whitespace +
+ // "Attribute values must be CSS identifiers [capture 5] or strings [capture 3 or capture 4]"
+ "*(?:'((?:\\\\.|[^\\\\'])*)'|\"((?:\\\\.|[^\\\\\"])*)\"|(" + identifier + "))|)" + whitespace +
+ "*\\]",
+
+ pseudos = ":(" + identifier + ")(?:\\((" +
+ // To reduce the number of selectors needing tokenize in the preFilter, prefer arguments:
+ // 1. quoted (capture 3; capture 4 or capture 5)
+ "('((?:\\\\.|[^\\\\'])*)'|\"((?:\\\\.|[^\\\\\"])*)\")|" +
+ // 2. simple (capture 6)
+ "((?:\\\\.|[^\\\\()[\\]]|" + attributes + ")*)|" +
+ // 3. anything else (capture 2)
+ ".*" +
+ ")\\)|)",
+
+ // Leading and non-escaped trailing whitespace, capturing some non-whitespace characters preceding the latter
+ rwhitespace = new RegExp( whitespace + "+", "g" ),
+ rtrim = new RegExp( "^" + whitespace + "+|((?:^|[^\\\\])(?:\\\\.)*)" + whitespace + "+$", "g" ),
+
+ rcomma = new RegExp( "^" + whitespace + "*," + whitespace + "*" ),
+ rcombinators = new RegExp( "^" + whitespace + "*([>+~]|" + whitespace + ")" + whitespace + "*" ),
+
+ rattributeQuotes = new RegExp( "=" + whitespace + "*([^\\]'\"]*?)" + whitespace + "*\\]", "g" ),
+
+ rpseudo = new RegExp( pseudos ),
+ ridentifier = new RegExp( "^" + identifier + "$" ),
+
+ matchExpr = {
+ "ID": new RegExp( "^#(" + identifier + ")" ),
+ "CLASS": new RegExp( "^\\.(" + identifier + ")" ),
+ "TAG": new RegExp( "^(" + identifier + "|[*])" ),
+ "ATTR": new RegExp( "^" + attributes ),
+ "PSEUDO": new RegExp( "^" + pseudos ),
+ "CHILD": new RegExp( "^:(only|first|last|nth|nth-last)-(child|of-type)(?:\\(" + whitespace +
+ "*(even|odd|(([+-]|)(\\d*)n|)" + whitespace + "*(?:([+-]|)" + whitespace +
+ "*(\\d+)|))" + whitespace + "*\\)|)", "i" ),
+ "bool": new RegExp( "^(?:" + booleans + ")$", "i" ),
+ // For use in libraries implementing .is()
+ // We use this for POS matching in `select`
+ "needsContext": new RegExp( "^" + whitespace + "*[>+~]|:(even|odd|eq|gt|lt|nth|first|last)(?:\\(" +
+ whitespace + "*((?:-\\d)?\\d*)" + whitespace + "*\\)|)(?=[^-]|$)", "i" )
+ },
+
+ rinputs = /^(?:input|select|textarea|button)$/i,
+ rheader = /^h\d$/i,
+
+ rnative = /^[^{]+\{\s*\[native \w/,
+
+ // Easily-parseable/retrievable ID or TAG or CLASS selectors
+ rquickExpr = /^(?:#([\w-]+)|(\w+)|\.([\w-]+))$/,
+
+ rsibling = /[+~]/,
+ rescape = /'|\\/g,
+
+ // CSS escapes http://www.w3.org/TR/CSS21/syndata.html#escaped-characters
+ runescape = new RegExp( "\\\\([\\da-f]{1,6}" + whitespace + "?|(" + whitespace + ")|.)", "ig" ),
+ funescape = function( _, escaped, escapedWhitespace ) {
+ var high = "0x" + escaped - 0x10000;
+ // NaN means non-codepoint
+ // Support: Firefox<24
+ // Workaround erroneous numeric interpretation of +"0x"
+ return high !== high || escapedWhitespace ?
+ escaped :
+ high < 0 ?
+ // BMP codepoint
+ String.fromCharCode( high + 0x10000 ) :
+ // Supplemental Plane codepoint (surrogate pair)
+ String.fromCharCode( high >> 10 | 0xD800, high & 0x3FF | 0xDC00 );
+ },
+
+ // Used for iframes
+ // See setDocument()
+ // Removing the function wrapper causes a "Permission Denied"
+ // error in IE
+ unloadHandler = function() {
+ setDocument();
+ };
+
+// Optimize for push.apply( _, NodeList )
+try {
+ push.apply(
+ (arr = slice.call( preferredDoc.childNodes )),
+ preferredDoc.childNodes
+ );
+ // Support: Android<4.0
+ // Detect silently failing push.apply
+ arr[ preferredDoc.childNodes.length ].nodeType;
+} catch ( e ) {
+ push = { apply: arr.length ?
+
+ // Leverage slice if possible
+ function( target, els ) {
+ push_native.apply( target, slice.call(els) );
+ } :
+
+ // Support: IE<9
+ // Otherwise append directly
+ function( target, els ) {
+ var j = target.length,
+ i = 0;
+ // Can't trust NodeList.length
+ while ( (target[j++] = els[i++]) ) {}
+ target.length = j - 1;
+ }
+ };
+}
+
+function Sizzle( selector, context, results, seed ) {
+ var m, i, elem, nid, nidselect, match, groups, newSelector,
+ newContext = context && context.ownerDocument,
+
+ // nodeType defaults to 9, since context defaults to document
+ nodeType = context ? context.nodeType : 9;
+
+ results = results || [];
+
+ // Return early from calls with invalid selector or context
+ if ( typeof selector !== "string" || !selector ||
+ nodeType !== 1 && nodeType !== 9 && nodeType !== 11 ) {
+
+ return results;
+ }
+
+ // Try to shortcut find operations (as opposed to filters) in HTML documents
+ if ( !seed ) {
+
+ if ( ( context ? context.ownerDocument || context : preferredDoc ) !== document ) {
+ setDocument( context );
+ }
+ context = context || document;
+
+ if ( documentIsHTML ) {
+
+ // If the selector is sufficiently simple, try using a "get*By*" DOM method
+ // (excepting DocumentFragment context, where the methods don't exist)
+ if ( nodeType !== 11 && (match = rquickExpr.exec( selector )) ) {
+
+ // ID selector
+ if ( (m = match[1]) ) {
+
+ // Document context
+ if ( nodeType === 9 ) {
+ if ( (elem = context.getElementById( m )) ) {
+
+ // Support: IE, Opera, Webkit
+ // TODO: identify versions
+ // getElementById can match elements by name instead of ID
+ if ( elem.id === m ) {
+ results.push( elem );
+ return results;
+ }
+ } else {
+ return results;
+ }
+
+ // Element context
+ } else {
+
+ // Support: IE, Opera, Webkit
+ // TODO: identify versions
+ // getElementById can match elements by name instead of ID
+ if ( newContext && (elem = newContext.getElementById( m )) &&
+ contains( context, elem ) &&
+ elem.id === m ) {
+
+ results.push( elem );
+ return results;
+ }
+ }
+
+ // Type selector
+ } else if ( match[2] ) {
+ push.apply( results, context.getElementsByTagName( selector ) );
+ return results;
+
+ // Class selector
+ } else if ( (m = match[3]) && support.getElementsByClassName &&
+ context.getElementsByClassName ) {
+
+ push.apply( results, context.getElementsByClassName( m ) );
+ return results;
+ }
+ }
+
+ // Take advantage of querySelectorAll
+ if ( support.qsa &&
+ !compilerCache[ selector + " " ] &&
+ (!rbuggyQSA || !rbuggyQSA.test( selector )) ) {
+
+ if ( nodeType !== 1 ) {
+ newContext = context;
+ newSelector = selector;
+
+ // qSA looks outside Element context, which is not what we want
+ // Thanks to Andrew Dupont for this workaround technique
+ // Support: IE <=8
+ // Exclude object elements
+ } else if ( context.nodeName.toLowerCase() !== "object" ) {
+
+ // Capture the context ID, setting it first if necessary
+ if ( (nid = context.getAttribute( "id" )) ) {
+ nid = nid.replace( rescape, "\\$&" );
+ } else {
+ context.setAttribute( "id", (nid = expando) );
+ }
+
+ // Prefix every selector in the list
+ groups = tokenize( selector );
+ i = groups.length;
+ nidselect = ridentifier.test( nid ) ? "#" + nid : "[id='" + nid + "']";
+ while ( i-- ) {
+ groups[i] = nidselect + " " + toSelector( groups[i] );
+ }
+ newSelector = groups.join( "," );
+
+ // Expand context for sibling selectors
+ newContext = rsibling.test( selector ) && testContext( context.parentNode ) ||
+ context;
+ }
+
+ if ( newSelector ) {
+ try {
+ push.apply( results,
+ newContext.querySelectorAll( newSelector )
+ );
+ return results;
+ } catch ( qsaError ) {
+ } finally {
+ if ( nid === expando ) {
+ context.removeAttribute( "id" );
+ }
+ }
+ }
+ }
+ }
+ }
+
+ // All others
+ return select( selector.replace( rtrim, "$1" ), context, results, seed );
+}
+
+/**
+ * Create key-value caches of limited size
+ * @returns {function(string, object)} Returns the Object data after storing it on itself with
+ * property name the (space-suffixed) string and (if the cache is larger than Expr.cacheLength)
+ * deleting the oldest entry
+ */
+function createCache() {
+ var keys = [];
+
+ function cache( key, value ) {
+ // Use (key + " ") to avoid collision with native prototype properties (see Issue #157)
+ if ( keys.push( key + " " ) > Expr.cacheLength ) {
+ // Only keep the most recent entries
+ delete cache[ keys.shift() ];
+ }
+ return (cache[ key + " " ] = value);
+ }
+ return cache;
+}
+
+/**
+ * Mark a function for special use by Sizzle
+ * @param {Function} fn The function to mark
+ */
+function markFunction( fn ) {
+ fn[ expando ] = true;
+ return fn;
+}
+
+/**
+ * Support testing using an element
+ * @param {Function} fn Passed the created div and expects a boolean result
+ */
+function assert( fn ) {
+ var div = document.createElement("div");
+
+ try {
+ return !!fn( div );
+ } catch (e) {
+ return false;
+ } finally {
+ // Remove from its parent by default
+ if ( div.parentNode ) {
+ div.parentNode.removeChild( div );
+ }
+ // release memory in IE
+ div = null;
+ }
+}
+
+/**
+ * Adds the same handler for all of the specified attrs
+ * @param {String} attrs Pipe-separated list of attributes
+ * @param {Function} handler The method that will be applied
+ */
+function addHandle( attrs, handler ) {
+ var arr = attrs.split("|"),
+ i = arr.length;
+
+ while ( i-- ) {
+ Expr.attrHandle[ arr[i] ] = handler;
+ }
+}
+
+/**
+ * Checks document order of two siblings
+ * @param {Element} a
+ * @param {Element} b
+ * @returns {Number} Returns less than 0 if a precedes b, greater than 0 if a follows b
+ */
+function siblingCheck( a, b ) {
+ var cur = b && a,
+ diff = cur && a.nodeType === 1 && b.nodeType === 1 &&
+ ( ~b.sourceIndex || MAX_NEGATIVE ) -
+ ( ~a.sourceIndex || MAX_NEGATIVE );
+
+ // Use IE sourceIndex if available on both nodes
+ if ( diff ) {
+ return diff;
+ }
+
+ // Check if b follows a
+ if ( cur ) {
+ while ( (cur = cur.nextSibling) ) {
+ if ( cur === b ) {
+ return -1;
+ }
+ }
+ }
+
+ return a ? 1 : -1;
+}
+
+/**
+ * Returns a function to use in pseudos for input types
+ * @param {String} type
+ */
+function createInputPseudo( type ) {
+ return function( elem ) {
+ var name = elem.nodeName.toLowerCase();
+ return name === "input" && elem.type === type;
+ };
+}
+
+/**
+ * Returns a function to use in pseudos for buttons
+ * @param {String} type
+ */
+function createButtonPseudo( type ) {
+ return function( elem ) {
+ var name = elem.nodeName.toLowerCase();
+ return (name === "input" || name === "button") && elem.type === type;
+ };
+}
+
+/**
+ * Returns a function to use in pseudos for positionals
+ * @param {Function} fn
+ */
+function createPositionalPseudo( fn ) {
+ return markFunction(function( argument ) {
+ argument = +argument;
+ return markFunction(function( seed, matches ) {
+ var j,
+ matchIndexes = fn( [], seed.length, argument ),
+ i = matchIndexes.length;
+
+ // Match elements found at the specified indexes
+ while ( i-- ) {
+ if ( seed[ (j = matchIndexes[i]) ] ) {
+ seed[j] = !(matches[j] = seed[j]);
+ }
+ }
+ });
+ });
+}
+
+/**
+ * Checks a node for validity as a Sizzle context
+ * @param {Element|Object=} context
+ * @returns {Element|Object|Boolean} The input node if acceptable, otherwise a falsy value
+ */
+function testContext( context ) {
+ return context && typeof context.getElementsByTagName !== "undefined" && context;
+}
+
+// Expose support vars for convenience
+support = Sizzle.support = {};
+
+/**
+ * Detects XML nodes
+ * @param {Element|Object} elem An element or a document
+ * @returns {Boolean} True iff elem is a non-HTML XML node
+ */
+isXML = Sizzle.isXML = function( elem ) {
+ // documentElement is verified for cases where it doesn't yet exist
+ // (such as loading iframes in IE - #4833)
+ var documentElement = elem && (elem.ownerDocument || elem).documentElement;
+ return documentElement ? documentElement.nodeName !== "HTML" : false;
+};
+
+/**
+ * Sets document-related variables once based on the current document
+ * @param {Element|Object} [doc] An element or document object to use to set the document
+ * @returns {Object} Returns the current document
+ */
+setDocument = Sizzle.setDocument = function( node ) {
+ var hasCompare, parent,
+ doc = node ? node.ownerDocument || node : preferredDoc;
+
+ // Return early if doc is invalid or already selected
+ if ( doc === document || doc.nodeType !== 9 || !doc.documentElement ) {
+ return document;
+ }
+
+ // Update global variables
+ document = doc;
+ docElem = document.documentElement;
+ documentIsHTML = !isXML( document );
+
+ // Support: IE 9-11, Edge
+ // Accessing iframe documents after unload throws "permission denied" errors (jQuery #13936)
+ if ( (parent = document.defaultView) && parent.top !== parent ) {
+ // Support: IE 11
+ if ( parent.addEventListener ) {
+ parent.addEventListener( "unload", unloadHandler, false );
+
+ // Support: IE 9 - 10 only
+ } else if ( parent.attachEvent ) {
+ parent.attachEvent( "onunload", unloadHandler );
+ }
+ }
+
+ /* Attributes
+ ---------------------------------------------------------------------- */
+
+ // Support: IE<8
+ // Verify that getAttribute really returns attributes and not properties
+ // (excepting IE8 booleans)
+ support.attributes = assert(function( div ) {
+ div.className = "i";
+ return !div.getAttribute("className");
+ });
+
+ /* getElement(s)By*
+ ---------------------------------------------------------------------- */
+
+ // Check if getElementsByTagName("*") returns only elements
+ support.getElementsByTagName = assert(function( div ) {
+ div.appendChild( document.createComment("") );
+ return !div.getElementsByTagName("*").length;
+ });
+
+ // Support: IE<9
+ support.getElementsByClassName = rnative.test( document.getElementsByClassName );
+
+ // Support: IE<10
+ // Check if getElementById returns elements by name
+ // The broken getElementById methods don't pick up programatically-set names,
+ // so use a roundabout getElementsByName test
+ support.getById = assert(function( div ) {
+ docElem.appendChild( div ).id = expando;
+ return !document.getElementsByName || !document.getElementsByName( expando ).length;
+ });
+
+ // ID find and filter
+ if ( support.getById ) {
+ Expr.find["ID"] = function( id, context ) {
+ if ( typeof context.getElementById !== "undefined" && documentIsHTML ) {
+ var m = context.getElementById( id );
+ return m ? [ m ] : [];
+ }
+ };
+ Expr.filter["ID"] = function( id ) {
+ var attrId = id.replace( runescape, funescape );
+ return function( elem ) {
+ return elem.getAttribute("id") === attrId;
+ };
+ };
+ } else {
+ // Support: IE6/7
+ // getElementById is not reliable as a find shortcut
+ delete Expr.find["ID"];
+
+ Expr.filter["ID"] = function( id ) {
+ var attrId = id.replace( runescape, funescape );
+ return function( elem ) {
+ var node = typeof elem.getAttributeNode !== "undefined" &&
+ elem.getAttributeNode("id");
+ return node && node.value === attrId;
+ };
+ };
+ }
+
+ // Tag
+ Expr.find["TAG"] = support.getElementsByTagName ?
+ function( tag, context ) {
+ if ( typeof context.getElementsByTagName !== "undefined" ) {
+ return context.getElementsByTagName( tag );
+
+ // DocumentFragment nodes don't have gEBTN
+ } else if ( support.qsa ) {
+ return context.querySelectorAll( tag );
+ }
+ } :
+
+ function( tag, context ) {
+ var elem,
+ tmp = [],
+ i = 0,
+ // By happy coincidence, a (broken) gEBTN appears on DocumentFragment nodes too
+ results = context.getElementsByTagName( tag );
+
+ // Filter out possible comments
+ if ( tag === "*" ) {
+ while ( (elem = results[i++]) ) {
+ if ( elem.nodeType === 1 ) {
+ tmp.push( elem );
+ }
+ }
+
+ return tmp;
+ }
+ return results;
+ };
+
+ // Class
+ Expr.find["CLASS"] = support.getElementsByClassName && function( className, context ) {
+ if ( typeof context.getElementsByClassName !== "undefined" && documentIsHTML ) {
+ return context.getElementsByClassName( className );
+ }
+ };
+
+ /* QSA/matchesSelector
+ ---------------------------------------------------------------------- */
+
+ // QSA and matchesSelector support
+
+ // matchesSelector(:active) reports false when true (IE9/Opera 11.5)
+ rbuggyMatches = [];
+
+ // qSa(:focus) reports false when true (Chrome 21)
+ // We allow this because of a bug in IE8/9 that throws an error
+ // whenever `document.activeElement` is accessed on an iframe
+ // So, we allow :focus to pass through QSA all the time to avoid the IE error
+ // See http://bugs.jquery.com/ticket/13378
+ rbuggyQSA = [];
+
+ if ( (support.qsa = rnative.test( document.querySelectorAll )) ) {
+ // Build QSA regex
+ // Regex strategy adopted from Diego Perini
+ assert(function( div ) {
+ // Select is set to empty string on purpose
+ // This is to test IE's treatment of not explicitly
+ // setting a boolean content attribute,
+ // since its presence should be enough
+ // http://bugs.jquery.com/ticket/12359
+ docElem.appendChild( div ).innerHTML = "" +
+ "";
+
+ // Support: IE8, Opera 11-12.16
+ // Nothing should be selected when empty strings follow ^= or $= or *=
+ // The test attribute must be unknown in Opera but "safe" for WinRT
+ // http://msdn.microsoft.com/en-us/library/ie/hh465388.aspx#attribute_section
+ if ( div.querySelectorAll("[msallowcapture^='']").length ) {
+ rbuggyQSA.push( "[*^$]=" + whitespace + "*(?:''|\"\")" );
+ }
+
+ // Support: IE8
+ // Boolean attributes and "value" are not treated correctly
+ if ( !div.querySelectorAll("[selected]").length ) {
+ rbuggyQSA.push( "\\[" + whitespace + "*(?:value|" + booleans + ")" );
+ }
+
+ // Support: Chrome<29, Android<4.4, Safari<7.0+, iOS<7.0+, PhantomJS<1.9.8+
+ if ( !div.querySelectorAll( "[id~=" + expando + "-]" ).length ) {
+ rbuggyQSA.push("~=");
+ }
+
+ // Webkit/Opera - :checked should return selected option elements
+ // http://www.w3.org/TR/2011/REC-css3-selectors-20110929/#checked
+ // IE8 throws error here and will not see later tests
+ if ( !div.querySelectorAll(":checked").length ) {
+ rbuggyQSA.push(":checked");
+ }
+
+ // Support: Safari 8+, iOS 8+
+ // https://bugs.webkit.org/show_bug.cgi?id=136851
+ // In-page `selector#id sibing-combinator selector` fails
+ if ( !div.querySelectorAll( "a#" + expando + "+*" ).length ) {
+ rbuggyQSA.push(".#.+[+~]");
+ }
+ });
+
+ assert(function( div ) {
+ // Support: Windows 8 Native Apps
+ // The type and name attributes are restricted during .innerHTML assignment
+ var input = document.createElement("input");
+ input.setAttribute( "type", "hidden" );
+ div.appendChild( input ).setAttribute( "name", "D" );
+
+ // Support: IE8
+ // Enforce case-sensitivity of name attribute
+ if ( div.querySelectorAll("[name=d]").length ) {
+ rbuggyQSA.push( "name" + whitespace + "*[*^$|!~]?=" );
+ }
+
+ // FF 3.5 - :enabled/:disabled and hidden elements (hidden elements are still enabled)
+ // IE8 throws error here and will not see later tests
+ if ( !div.querySelectorAll(":enabled").length ) {
+ rbuggyQSA.push( ":enabled", ":disabled" );
+ }
+
+ // Opera 10-11 does not throw on post-comma invalid pseudos
+ div.querySelectorAll("*,:x");
+ rbuggyQSA.push(",.*:");
+ });
+ }
+
+ if ( (support.matchesSelector = rnative.test( (matches = docElem.matches ||
+ docElem.webkitMatchesSelector ||
+ docElem.mozMatchesSelector ||
+ docElem.oMatchesSelector ||
+ docElem.msMatchesSelector) )) ) {
+
+ assert(function( div ) {
+ // Check to see if it's possible to do matchesSelector
+ // on a disconnected node (IE 9)
+ support.disconnectedMatch = matches.call( div, "div" );
+
+ // This should fail with an exception
+ // Gecko does not error, returns false instead
+ matches.call( div, "[s!='']:x" );
+ rbuggyMatches.push( "!=", pseudos );
+ });
+ }
+
+ rbuggyQSA = rbuggyQSA.length && new RegExp( rbuggyQSA.join("|") );
+ rbuggyMatches = rbuggyMatches.length && new RegExp( rbuggyMatches.join("|") );
+
+ /* Contains
+ ---------------------------------------------------------------------- */
+ hasCompare = rnative.test( docElem.compareDocumentPosition );
+
+ // Element contains another
+ // Purposefully self-exclusive
+ // As in, an element does not contain itself
+ contains = hasCompare || rnative.test( docElem.contains ) ?
+ function( a, b ) {
+ var adown = a.nodeType === 9 ? a.documentElement : a,
+ bup = b && b.parentNode;
+ return a === bup || !!( bup && bup.nodeType === 1 && (
+ adown.contains ?
+ adown.contains( bup ) :
+ a.compareDocumentPosition && a.compareDocumentPosition( bup ) & 16
+ ));
+ } :
+ function( a, b ) {
+ if ( b ) {
+ while ( (b = b.parentNode) ) {
+ if ( b === a ) {
+ return true;
+ }
+ }
+ }
+ return false;
+ };
+
+ /* Sorting
+ ---------------------------------------------------------------------- */
+
+ // Document order sorting
+ sortOrder = hasCompare ?
+ function( a, b ) {
+
+ // Flag for duplicate removal
+ if ( a === b ) {
+ hasDuplicate = true;
+ return 0;
+ }
+
+ // Sort on method existence if only one input has compareDocumentPosition
+ var compare = !a.compareDocumentPosition - !b.compareDocumentPosition;
+ if ( compare ) {
+ return compare;
+ }
+
+ // Calculate position if both inputs belong to the same document
+ compare = ( a.ownerDocument || a ) === ( b.ownerDocument || b ) ?
+ a.compareDocumentPosition( b ) :
+
+ // Otherwise we know they are disconnected
+ 1;
+
+ // Disconnected nodes
+ if ( compare & 1 ||
+ (!support.sortDetached && b.compareDocumentPosition( a ) === compare) ) {
+
+ // Choose the first element that is related to our preferred document
+ if ( a === document || a.ownerDocument === preferredDoc && contains(preferredDoc, a) ) {
+ return -1;
+ }
+ if ( b === document || b.ownerDocument === preferredDoc && contains(preferredDoc, b) ) {
+ return 1;
+ }
+
+ // Maintain original order
+ return sortInput ?
+ ( indexOf( sortInput, a ) - indexOf( sortInput, b ) ) :
+ 0;
+ }
+
+ return compare & 4 ? -1 : 1;
+ } :
+ function( a, b ) {
+ // Exit early if the nodes are identical
+ if ( a === b ) {
+ hasDuplicate = true;
+ return 0;
+ }
+
+ var cur,
+ i = 0,
+ aup = a.parentNode,
+ bup = b.parentNode,
+ ap = [ a ],
+ bp = [ b ];
+
+ // Parentless nodes are either documents or disconnected
+ if ( !aup || !bup ) {
+ return a === document ? -1 :
+ b === document ? 1 :
+ aup ? -1 :
+ bup ? 1 :
+ sortInput ?
+ ( indexOf( sortInput, a ) - indexOf( sortInput, b ) ) :
+ 0;
+
+ // If the nodes are siblings, we can do a quick check
+ } else if ( aup === bup ) {
+ return siblingCheck( a, b );
+ }
+
+ // Otherwise we need full lists of their ancestors for comparison
+ cur = a;
+ while ( (cur = cur.parentNode) ) {
+ ap.unshift( cur );
+ }
+ cur = b;
+ while ( (cur = cur.parentNode) ) {
+ bp.unshift( cur );
+ }
+
+ // Walk down the tree looking for a discrepancy
+ while ( ap[i] === bp[i] ) {
+ i++;
+ }
+
+ return i ?
+ // Do a sibling check if the nodes have a common ancestor
+ siblingCheck( ap[i], bp[i] ) :
+
+ // Otherwise nodes in our document sort first
+ ap[i] === preferredDoc ? -1 :
+ bp[i] === preferredDoc ? 1 :
+ 0;
+ };
+
+ return document;
+};
+
+Sizzle.matches = function( expr, elements ) {
+ return Sizzle( expr, null, null, elements );
+};
+
+Sizzle.matchesSelector = function( elem, expr ) {
+ // Set document vars if needed
+ if ( ( elem.ownerDocument || elem ) !== document ) {
+ setDocument( elem );
+ }
+
+ // Make sure that attribute selectors are quoted
+ expr = expr.replace( rattributeQuotes, "='$1']" );
+
+ if ( support.matchesSelector && documentIsHTML &&
+ !compilerCache[ expr + " " ] &&
+ ( !rbuggyMatches || !rbuggyMatches.test( expr ) ) &&
+ ( !rbuggyQSA || !rbuggyQSA.test( expr ) ) ) {
+
+ try {
+ var ret = matches.call( elem, expr );
+
+ // IE 9's matchesSelector returns false on disconnected nodes
+ if ( ret || support.disconnectedMatch ||
+ // As well, disconnected nodes are said to be in a document
+ // fragment in IE 9
+ elem.document && elem.document.nodeType !== 11 ) {
+ return ret;
+ }
+ } catch (e) {}
+ }
+
+ return Sizzle( expr, document, null, [ elem ] ).length > 0;
+};
+
+Sizzle.contains = function( context, elem ) {
+ // Set document vars if needed
+ if ( ( context.ownerDocument || context ) !== document ) {
+ setDocument( context );
+ }
+ return contains( context, elem );
+};
+
+Sizzle.attr = function( elem, name ) {
+ // Set document vars if needed
+ if ( ( elem.ownerDocument || elem ) !== document ) {
+ setDocument( elem );
+ }
+
+ var fn = Expr.attrHandle[ name.toLowerCase() ],
+ // Don't get fooled by Object.prototype properties (jQuery #13807)
+ val = fn && hasOwn.call( Expr.attrHandle, name.toLowerCase() ) ?
+ fn( elem, name, !documentIsHTML ) :
+ undefined;
+
+ return val !== undefined ?
+ val :
+ support.attributes || !documentIsHTML ?
+ elem.getAttribute( name ) :
+ (val = elem.getAttributeNode(name)) && val.specified ?
+ val.value :
+ null;
+};
+
+Sizzle.error = function( msg ) {
+ throw new Error( "Syntax error, unrecognized expression: " + msg );
+};
+
+/**
+ * Document sorting and removing duplicates
+ * @param {ArrayLike} results
+ */
+Sizzle.uniqueSort = function( results ) {
+ var elem,
+ duplicates = [],
+ j = 0,
+ i = 0;
+
+ // Unless we *know* we can detect duplicates, assume their presence
+ hasDuplicate = !support.detectDuplicates;
+ sortInput = !support.sortStable && results.slice( 0 );
+ results.sort( sortOrder );
+
+ if ( hasDuplicate ) {
+ while ( (elem = results[i++]) ) {
+ if ( elem === results[ i ] ) {
+ j = duplicates.push( i );
+ }
+ }
+ while ( j-- ) {
+ results.splice( duplicates[ j ], 1 );
+ }
+ }
+
+ // Clear input after sorting to release objects
+ // See https://github.com/jquery/sizzle/pull/225
+ sortInput = null;
+
+ return results;
+};
+
+/**
+ * Utility function for retrieving the text value of an array of DOM nodes
+ * @param {Array|Element} elem
+ */
+getText = Sizzle.getText = function( elem ) {
+ var node,
+ ret = "",
+ i = 0,
+ nodeType = elem.nodeType;
+
+ if ( !nodeType ) {
+ // If no nodeType, this is expected to be an array
+ while ( (node = elem[i++]) ) {
+ // Do not traverse comment nodes
+ ret += getText( node );
+ }
+ } else if ( nodeType === 1 || nodeType === 9 || nodeType === 11 ) {
+ // Use textContent for elements
+ // innerText usage removed for consistency of new lines (jQuery #11153)
+ if ( typeof elem.textContent === "string" ) {
+ return elem.textContent;
+ } else {
+ // Traverse its children
+ for ( elem = elem.firstChild; elem; elem = elem.nextSibling ) {
+ ret += getText( elem );
+ }
+ }
+ } else if ( nodeType === 3 || nodeType === 4 ) {
+ return elem.nodeValue;
+ }
+ // Do not include comment or processing instruction nodes
+
+ return ret;
+};
+
+Expr = Sizzle.selectors = {
+
+ // Can be adjusted by the user
+ cacheLength: 50,
+
+ createPseudo: markFunction,
+
+ match: matchExpr,
+
+ attrHandle: {},
+
+ find: {},
+
+ relative: {
+ ">": { dir: "parentNode", first: true },
+ " ": { dir: "parentNode" },
+ "+": { dir: "previousSibling", first: true },
+ "~": { dir: "previousSibling" }
+ },
+
+ preFilter: {
+ "ATTR": function( match ) {
+ match[1] = match[1].replace( runescape, funescape );
+
+ // Move the given value to match[3] whether quoted or unquoted
+ match[3] = ( match[3] || match[4] || match[5] || "" ).replace( runescape, funescape );
+
+ if ( match[2] === "~=" ) {
+ match[3] = " " + match[3] + " ";
+ }
+
+ return match.slice( 0, 4 );
+ },
+
+ "CHILD": function( match ) {
+ /* matches from matchExpr["CHILD"]
+ 1 type (only|nth|...)
+ 2 what (child|of-type)
+ 3 argument (even|odd|\d*|\d*n([+-]\d+)?|...)
+ 4 xn-component of xn+y argument ([+-]?\d*n|)
+ 5 sign of xn-component
+ 6 x of xn-component
+ 7 sign of y-component
+ 8 y of y-component
+ */
+ match[1] = match[1].toLowerCase();
+
+ if ( match[1].slice( 0, 3 ) === "nth" ) {
+ // nth-* requires argument
+ if ( !match[3] ) {
+ Sizzle.error( match[0] );
+ }
+
+ // numeric x and y parameters for Expr.filter.CHILD
+ // remember that false/true cast respectively to 0/1
+ match[4] = +( match[4] ? match[5] + (match[6] || 1) : 2 * ( match[3] === "even" || match[3] === "odd" ) );
+ match[5] = +( ( match[7] + match[8] ) || match[3] === "odd" );
+
+ // other types prohibit arguments
+ } else if ( match[3] ) {
+ Sizzle.error( match[0] );
+ }
+
+ return match;
+ },
+
+ "PSEUDO": function( match ) {
+ var excess,
+ unquoted = !match[6] && match[2];
+
+ if ( matchExpr["CHILD"].test( match[0] ) ) {
+ return null;
+ }
+
+ // Accept quoted arguments as-is
+ if ( match[3] ) {
+ match[2] = match[4] || match[5] || "";
+
+ // Strip excess characters from unquoted arguments
+ } else if ( unquoted && rpseudo.test( unquoted ) &&
+ // Get excess from tokenize (recursively)
+ (excess = tokenize( unquoted, true )) &&
+ // advance to the next closing parenthesis
+ (excess = unquoted.indexOf( ")", unquoted.length - excess ) - unquoted.length) ) {
+
+ // excess is a negative index
+ match[0] = match[0].slice( 0, excess );
+ match[2] = unquoted.slice( 0, excess );
+ }
+
+ // Return only captures needed by the pseudo filter method (type and argument)
+ return match.slice( 0, 3 );
+ }
+ },
+
+ filter: {
+
+ "TAG": function( nodeNameSelector ) {
+ var nodeName = nodeNameSelector.replace( runescape, funescape ).toLowerCase();
+ return nodeNameSelector === "*" ?
+ function() { return true; } :
+ function( elem ) {
+ return elem.nodeName && elem.nodeName.toLowerCase() === nodeName;
+ };
+ },
+
+ "CLASS": function( className ) {
+ var pattern = classCache[ className + " " ];
+
+ return pattern ||
+ (pattern = new RegExp( "(^|" + whitespace + ")" + className + "(" + whitespace + "|$)" )) &&
+ classCache( className, function( elem ) {
+ return pattern.test( typeof elem.className === "string" && elem.className || typeof elem.getAttribute !== "undefined" && elem.getAttribute("class") || "" );
+ });
+ },
+
+ "ATTR": function( name, operator, check ) {
+ return function( elem ) {
+ var result = Sizzle.attr( elem, name );
+
+ if ( result == null ) {
+ return operator === "!=";
+ }
+ if ( !operator ) {
+ return true;
+ }
+
+ result += "";
+
+ return operator === "=" ? result === check :
+ operator === "!=" ? result !== check :
+ operator === "^=" ? check && result.indexOf( check ) === 0 :
+ operator === "*=" ? check && result.indexOf( check ) > -1 :
+ operator === "$=" ? check && result.slice( -check.length ) === check :
+ operator === "~=" ? ( " " + result.replace( rwhitespace, " " ) + " " ).indexOf( check ) > -1 :
+ operator === "|=" ? result === check || result.slice( 0, check.length + 1 ) === check + "-" :
+ false;
+ };
+ },
+
+ "CHILD": function( type, what, argument, first, last ) {
+ var simple = type.slice( 0, 3 ) !== "nth",
+ forward = type.slice( -4 ) !== "last",
+ ofType = what === "of-type";
+
+ return first === 1 && last === 0 ?
+
+ // Shortcut for :nth-*(n)
+ function( elem ) {
+ return !!elem.parentNode;
+ } :
+
+ function( elem, context, xml ) {
+ var cache, uniqueCache, outerCache, node, nodeIndex, start,
+ dir = simple !== forward ? "nextSibling" : "previousSibling",
+ parent = elem.parentNode,
+ name = ofType && elem.nodeName.toLowerCase(),
+ useCache = !xml && !ofType,
+ diff = false;
+
+ if ( parent ) {
+
+ // :(first|last|only)-(child|of-type)
+ if ( simple ) {
+ while ( dir ) {
+ node = elem;
+ while ( (node = node[ dir ]) ) {
+ if ( ofType ?
+ node.nodeName.toLowerCase() === name :
+ node.nodeType === 1 ) {
+
+ return false;
+ }
+ }
+ // Reverse direction for :only-* (if we haven't yet done so)
+ start = dir = type === "only" && !start && "nextSibling";
+ }
+ return true;
+ }
+
+ start = [ forward ? parent.firstChild : parent.lastChild ];
+
+ // non-xml :nth-child(...) stores cache data on `parent`
+ if ( forward && useCache ) {
+
+ // Seek `elem` from a previously-cached index
+
+ // ...in a gzip-friendly way
+ node = parent;
+ outerCache = node[ expando ] || (node[ expando ] = {});
+
+ // Support: IE <9 only
+ // Defend against cloned attroperties (jQuery gh-1709)
+ uniqueCache = outerCache[ node.uniqueID ] ||
+ (outerCache[ node.uniqueID ] = {});
+
+ cache = uniqueCache[ type ] || [];
+ nodeIndex = cache[ 0 ] === dirruns && cache[ 1 ];
+ diff = nodeIndex && cache[ 2 ];
+ node = nodeIndex && parent.childNodes[ nodeIndex ];
+
+ while ( (node = ++nodeIndex && node && node[ dir ] ||
+
+ // Fallback to seeking `elem` from the start
+ (diff = nodeIndex = 0) || start.pop()) ) {
+
+ // When found, cache indexes on `parent` and break
+ if ( node.nodeType === 1 && ++diff && node === elem ) {
+ uniqueCache[ type ] = [ dirruns, nodeIndex, diff ];
+ break;
+ }
+ }
+
+ } else {
+ // Use previously-cached element index if available
+ if ( useCache ) {
+ // ...in a gzip-friendly way
+ node = elem;
+ outerCache = node[ expando ] || (node[ expando ] = {});
+
+ // Support: IE <9 only
+ // Defend against cloned attroperties (jQuery gh-1709)
+ uniqueCache = outerCache[ node.uniqueID ] ||
+ (outerCache[ node.uniqueID ] = {});
+
+ cache = uniqueCache[ type ] || [];
+ nodeIndex = cache[ 0 ] === dirruns && cache[ 1 ];
+ diff = nodeIndex;
+ }
+
+ // xml :nth-child(...)
+ // or :nth-last-child(...) or :nth(-last)?-of-type(...)
+ if ( diff === false ) {
+ // Use the same loop as above to seek `elem` from the start
+ while ( (node = ++nodeIndex && node && node[ dir ] ||
+ (diff = nodeIndex = 0) || start.pop()) ) {
+
+ if ( ( ofType ?
+ node.nodeName.toLowerCase() === name :
+ node.nodeType === 1 ) &&
+ ++diff ) {
+
+ // Cache the index of each encountered element
+ if ( useCache ) {
+ outerCache = node[ expando ] || (node[ expando ] = {});
+
+ // Support: IE <9 only
+ // Defend against cloned attroperties (jQuery gh-1709)
+ uniqueCache = outerCache[ node.uniqueID ] ||
+ (outerCache[ node.uniqueID ] = {});
+
+ uniqueCache[ type ] = [ dirruns, diff ];
+ }
+
+ if ( node === elem ) {
+ break;
+ }
+ }
+ }
+ }
+ }
+
+ // Incorporate the offset, then check against cycle size
+ diff -= last;
+ return diff === first || ( diff % first === 0 && diff / first >= 0 );
+ }
+ };
+ },
+
+ "PSEUDO": function( pseudo, argument ) {
+ // pseudo-class names are case-insensitive
+ // http://www.w3.org/TR/selectors/#pseudo-classes
+ // Prioritize by case sensitivity in case custom pseudos are added with uppercase letters
+ // Remember that setFilters inherits from pseudos
+ var args,
+ fn = Expr.pseudos[ pseudo ] || Expr.setFilters[ pseudo.toLowerCase() ] ||
+ Sizzle.error( "unsupported pseudo: " + pseudo );
+
+ // The user may use createPseudo to indicate that
+ // arguments are needed to create the filter function
+ // just as Sizzle does
+ if ( fn[ expando ] ) {
+ return fn( argument );
+ }
+
+ // But maintain support for old signatures
+ if ( fn.length > 1 ) {
+ args = [ pseudo, pseudo, "", argument ];
+ return Expr.setFilters.hasOwnProperty( pseudo.toLowerCase() ) ?
+ markFunction(function( seed, matches ) {
+ var idx,
+ matched = fn( seed, argument ),
+ i = matched.length;
+ while ( i-- ) {
+ idx = indexOf( seed, matched[i] );
+ seed[ idx ] = !( matches[ idx ] = matched[i] );
+ }
+ }) :
+ function( elem ) {
+ return fn( elem, 0, args );
+ };
+ }
+
+ return fn;
+ }
+ },
+
+ pseudos: {
+ // Potentially complex pseudos
+ "not": markFunction(function( selector ) {
+ // Trim the selector passed to compile
+ // to avoid treating leading and trailing
+ // spaces as combinators
+ var input = [],
+ results = [],
+ matcher = compile( selector.replace( rtrim, "$1" ) );
+
+ return matcher[ expando ] ?
+ markFunction(function( seed, matches, context, xml ) {
+ var elem,
+ unmatched = matcher( seed, null, xml, [] ),
+ i = seed.length;
+
+ // Match elements unmatched by `matcher`
+ while ( i-- ) {
+ if ( (elem = unmatched[i]) ) {
+ seed[i] = !(matches[i] = elem);
+ }
+ }
+ }) :
+ function( elem, context, xml ) {
+ input[0] = elem;
+ matcher( input, null, xml, results );
+ // Don't keep the element (issue #299)
+ input[0] = null;
+ return !results.pop();
+ };
+ }),
+
+ "has": markFunction(function( selector ) {
+ return function( elem ) {
+ return Sizzle( selector, elem ).length > 0;
+ };
+ }),
+
+ "contains": markFunction(function( text ) {
+ text = text.replace( runescape, funescape );
+ return function( elem ) {
+ return ( elem.textContent || elem.innerText || getText( elem ) ).indexOf( text ) > -1;
+ };
+ }),
+
+ // "Whether an element is represented by a :lang() selector
+ // is based solely on the element's language value
+ // being equal to the identifier C,
+ // or beginning with the identifier C immediately followed by "-".
+ // The matching of C against the element's language value is performed case-insensitively.
+ // The identifier C does not have to be a valid language name."
+ // http://www.w3.org/TR/selectors/#lang-pseudo
+ "lang": markFunction( function( lang ) {
+ // lang value must be a valid identifier
+ if ( !ridentifier.test(lang || "") ) {
+ Sizzle.error( "unsupported lang: " + lang );
+ }
+ lang = lang.replace( runescape, funescape ).toLowerCase();
+ return function( elem ) {
+ var elemLang;
+ do {
+ if ( (elemLang = documentIsHTML ?
+ elem.lang :
+ elem.getAttribute("xml:lang") || elem.getAttribute("lang")) ) {
+
+ elemLang = elemLang.toLowerCase();
+ return elemLang === lang || elemLang.indexOf( lang + "-" ) === 0;
+ }
+ } while ( (elem = elem.parentNode) && elem.nodeType === 1 );
+ return false;
+ };
+ }),
+
+ // Miscellaneous
+ "target": function( elem ) {
+ var hash = window.location && window.location.hash;
+ return hash && hash.slice( 1 ) === elem.id;
+ },
+
+ "root": function( elem ) {
+ return elem === docElem;
+ },
+
+ "focus": function( elem ) {
+ return elem === document.activeElement && (!document.hasFocus || document.hasFocus()) && !!(elem.type || elem.href || ~elem.tabIndex);
+ },
+
+ // Boolean properties
+ "enabled": function( elem ) {
+ return elem.disabled === false;
+ },
+
+ "disabled": function( elem ) {
+ return elem.disabled === true;
+ },
+
+ "checked": function( elem ) {
+ // In CSS3, :checked should return both checked and selected elements
+ // http://www.w3.org/TR/2011/REC-css3-selectors-20110929/#checked
+ var nodeName = elem.nodeName.toLowerCase();
+ return (nodeName === "input" && !!elem.checked) || (nodeName === "option" && !!elem.selected);
+ },
+
+ "selected": function( elem ) {
+ // Accessing this property makes selected-by-default
+ // options in Safari work properly
+ if ( elem.parentNode ) {
+ elem.parentNode.selectedIndex;
+ }
+
+ return elem.selected === true;
+ },
+
+ // Contents
+ "empty": function( elem ) {
+ // http://www.w3.org/TR/selectors/#empty-pseudo
+ // :empty is negated by element (1) or content nodes (text: 3; cdata: 4; entity ref: 5),
+ // but not by others (comment: 8; processing instruction: 7; etc.)
+ // nodeType < 6 works because attributes (2) do not appear as children
+ for ( elem = elem.firstChild; elem; elem = elem.nextSibling ) {
+ if ( elem.nodeType < 6 ) {
+ return false;
+ }
+ }
+ return true;
+ },
+
+ "parent": function( elem ) {
+ return !Expr.pseudos["empty"]( elem );
+ },
+
+ // Element/input types
+ "header": function( elem ) {
+ return rheader.test( elem.nodeName );
+ },
+
+ "input": function( elem ) {
+ return rinputs.test( elem.nodeName );
+ },
+
+ "button": function( elem ) {
+ var name = elem.nodeName.toLowerCase();
+ return name === "input" && elem.type === "button" || name === "button";
+ },
+
+ "text": function( elem ) {
+ var attr;
+ return elem.nodeName.toLowerCase() === "input" &&
+ elem.type === "text" &&
+
+ // Support: IE<8
+ // New HTML5 attribute values (e.g., "search") appear with elem.type === "text"
+ ( (attr = elem.getAttribute("type")) == null || attr.toLowerCase() === "text" );
+ },
+
+ // Position-in-collection
+ "first": createPositionalPseudo(function() {
+ return [ 0 ];
+ }),
+
+ "last": createPositionalPseudo(function( matchIndexes, length ) {
+ return [ length - 1 ];
+ }),
+
+ "eq": createPositionalPseudo(function( matchIndexes, length, argument ) {
+ return [ argument < 0 ? argument + length : argument ];
+ }),
+
+ "even": createPositionalPseudo(function( matchIndexes, length ) {
+ var i = 0;
+ for ( ; i < length; i += 2 ) {
+ matchIndexes.push( i );
+ }
+ return matchIndexes;
+ }),
+
+ "odd": createPositionalPseudo(function( matchIndexes, length ) {
+ var i = 1;
+ for ( ; i < length; i += 2 ) {
+ matchIndexes.push( i );
+ }
+ return matchIndexes;
+ }),
+
+ "lt": createPositionalPseudo(function( matchIndexes, length, argument ) {
+ var i = argument < 0 ? argument + length : argument;
+ for ( ; --i >= 0; ) {
+ matchIndexes.push( i );
+ }
+ return matchIndexes;
+ }),
+
+ "gt": createPositionalPseudo(function( matchIndexes, length, argument ) {
+ var i = argument < 0 ? argument + length : argument;
+ for ( ; ++i < length; ) {
+ matchIndexes.push( i );
+ }
+ return matchIndexes;
+ })
+ }
+};
+
+Expr.pseudos["nth"] = Expr.pseudos["eq"];
+
+// Add button/input type pseudos
+for ( i in { radio: true, checkbox: true, file: true, password: true, image: true } ) {
+ Expr.pseudos[ i ] = createInputPseudo( i );
+}
+for ( i in { submit: true, reset: true } ) {
+ Expr.pseudos[ i ] = createButtonPseudo( i );
+}
+
+// Easy API for creating new setFilters
+function setFilters() {}
+setFilters.prototype = Expr.filters = Expr.pseudos;
+Expr.setFilters = new setFilters();
+
+tokenize = Sizzle.tokenize = function( selector, parseOnly ) {
+ var matched, match, tokens, type,
+ soFar, groups, preFilters,
+ cached = tokenCache[ selector + " " ];
+
+ if ( cached ) {
+ return parseOnly ? 0 : cached.slice( 0 );
+ }
+
+ soFar = selector;
+ groups = [];
+ preFilters = Expr.preFilter;
+
+ while ( soFar ) {
+
+ // Comma and first run
+ if ( !matched || (match = rcomma.exec( soFar )) ) {
+ if ( match ) {
+ // Don't consume trailing commas as valid
+ soFar = soFar.slice( match[0].length ) || soFar;
+ }
+ groups.push( (tokens = []) );
+ }
+
+ matched = false;
+
+ // Combinators
+ if ( (match = rcombinators.exec( soFar )) ) {
+ matched = match.shift();
+ tokens.push({
+ value: matched,
+ // Cast descendant combinators to space
+ type: match[0].replace( rtrim, " " )
+ });
+ soFar = soFar.slice( matched.length );
+ }
+
+ // Filters
+ for ( type in Expr.filter ) {
+ if ( (match = matchExpr[ type ].exec( soFar )) && (!preFilters[ type ] ||
+ (match = preFilters[ type ]( match ))) ) {
+ matched = match.shift();
+ tokens.push({
+ value: matched,
+ type: type,
+ matches: match
+ });
+ soFar = soFar.slice( matched.length );
+ }
+ }
+
+ if ( !matched ) {
+ break;
+ }
+ }
+
+ // Return the length of the invalid excess
+ // if we're just parsing
+ // Otherwise, throw an error or return tokens
+ return parseOnly ?
+ soFar.length :
+ soFar ?
+ Sizzle.error( selector ) :
+ // Cache the tokens
+ tokenCache( selector, groups ).slice( 0 );
+};
+
+function toSelector( tokens ) {
+ var i = 0,
+ len = tokens.length,
+ selector = "";
+ for ( ; i < len; i++ ) {
+ selector += tokens[i].value;
+ }
+ return selector;
+}
+
+function addCombinator( matcher, combinator, base ) {
+ var dir = combinator.dir,
+ checkNonElements = base && dir === "parentNode",
+ doneName = done++;
+
+ return combinator.first ?
+ // Check against closest ancestor/preceding element
+ function( elem, context, xml ) {
+ while ( (elem = elem[ dir ]) ) {
+ if ( elem.nodeType === 1 || checkNonElements ) {
+ return matcher( elem, context, xml );
+ }
+ }
+ } :
+
+ // Check against all ancestor/preceding elements
+ function( elem, context, xml ) {
+ var oldCache, uniqueCache, outerCache,
+ newCache = [ dirruns, doneName ];
+
+ // We can't set arbitrary data on XML nodes, so they don't benefit from combinator caching
+ if ( xml ) {
+ while ( (elem = elem[ dir ]) ) {
+ if ( elem.nodeType === 1 || checkNonElements ) {
+ if ( matcher( elem, context, xml ) ) {
+ return true;
+ }
+ }
+ }
+ } else {
+ while ( (elem = elem[ dir ]) ) {
+ if ( elem.nodeType === 1 || checkNonElements ) {
+ outerCache = elem[ expando ] || (elem[ expando ] = {});
+
+ // Support: IE <9 only
+ // Defend against cloned attroperties (jQuery gh-1709)
+ uniqueCache = outerCache[ elem.uniqueID ] || (outerCache[ elem.uniqueID ] = {});
+
+ if ( (oldCache = uniqueCache[ dir ]) &&
+ oldCache[ 0 ] === dirruns && oldCache[ 1 ] === doneName ) {
+
+ // Assign to newCache so results back-propagate to previous elements
+ return (newCache[ 2 ] = oldCache[ 2 ]);
+ } else {
+ // Reuse newcache so results back-propagate to previous elements
+ uniqueCache[ dir ] = newCache;
+
+ // A match means we're done; a fail means we have to keep checking
+ if ( (newCache[ 2 ] = matcher( elem, context, xml )) ) {
+ return true;
+ }
+ }
+ }
+ }
+ }
+ };
+}
+
+function elementMatcher( matchers ) {
+ return matchers.length > 1 ?
+ function( elem, context, xml ) {
+ var i = matchers.length;
+ while ( i-- ) {
+ if ( !matchers[i]( elem, context, xml ) ) {
+ return false;
+ }
+ }
+ return true;
+ } :
+ matchers[0];
+}
+
+function multipleContexts( selector, contexts, results ) {
+ var i = 0,
+ len = contexts.length;
+ for ( ; i < len; i++ ) {
+ Sizzle( selector, contexts[i], results );
+ }
+ return results;
+}
+
+function condense( unmatched, map, filter, context, xml ) {
+ var elem,
+ newUnmatched = [],
+ i = 0,
+ len = unmatched.length,
+ mapped = map != null;
+
+ for ( ; i < len; i++ ) {
+ if ( (elem = unmatched[i]) ) {
+ if ( !filter || filter( elem, context, xml ) ) {
+ newUnmatched.push( elem );
+ if ( mapped ) {
+ map.push( i );
+ }
+ }
+ }
+ }
+
+ return newUnmatched;
+}
+
+function setMatcher( preFilter, selector, matcher, postFilter, postFinder, postSelector ) {
+ if ( postFilter && !postFilter[ expando ] ) {
+ postFilter = setMatcher( postFilter );
+ }
+ if ( postFinder && !postFinder[ expando ] ) {
+ postFinder = setMatcher( postFinder, postSelector );
+ }
+ return markFunction(function( seed, results, context, xml ) {
+ var temp, i, elem,
+ preMap = [],
+ postMap = [],
+ preexisting = results.length,
+
+ // Get initial elements from seed or context
+ elems = seed || multipleContexts( selector || "*", context.nodeType ? [ context ] : context, [] ),
+
+ // Prefilter to get matcher input, preserving a map for seed-results synchronization
+ matcherIn = preFilter && ( seed || !selector ) ?
+ condense( elems, preMap, preFilter, context, xml ) :
+ elems,
+
+ matcherOut = matcher ?
+ // If we have a postFinder, or filtered seed, or non-seed postFilter or preexisting results,
+ postFinder || ( seed ? preFilter : preexisting || postFilter ) ?
+
+ // ...intermediate processing is necessary
+ [] :
+
+ // ...otherwise use results directly
+ results :
+ matcherIn;
+
+ // Find primary matches
+ if ( matcher ) {
+ matcher( matcherIn, matcherOut, context, xml );
+ }
+
+ // Apply postFilter
+ if ( postFilter ) {
+ temp = condense( matcherOut, postMap );
+ postFilter( temp, [], context, xml );
+
+ // Un-match failing elements by moving them back to matcherIn
+ i = temp.length;
+ while ( i-- ) {
+ if ( (elem = temp[i]) ) {
+ matcherOut[ postMap[i] ] = !(matcherIn[ postMap[i] ] = elem);
+ }
+ }
+ }
+
+ if ( seed ) {
+ if ( postFinder || preFilter ) {
+ if ( postFinder ) {
+ // Get the final matcherOut by condensing this intermediate into postFinder contexts
+ temp = [];
+ i = matcherOut.length;
+ while ( i-- ) {
+ if ( (elem = matcherOut[i]) ) {
+ // Restore matcherIn since elem is not yet a final match
+ temp.push( (matcherIn[i] = elem) );
+ }
+ }
+ postFinder( null, (matcherOut = []), temp, xml );
+ }
+
+ // Move matched elements from seed to results to keep them synchronized
+ i = matcherOut.length;
+ while ( i-- ) {
+ if ( (elem = matcherOut[i]) &&
+ (temp = postFinder ? indexOf( seed, elem ) : preMap[i]) > -1 ) {
+
+ seed[temp] = !(results[temp] = elem);
+ }
+ }
+ }
+
+ // Add elements to results, through postFinder if defined
+ } else {
+ matcherOut = condense(
+ matcherOut === results ?
+ matcherOut.splice( preexisting, matcherOut.length ) :
+ matcherOut
+ );
+ if ( postFinder ) {
+ postFinder( null, results, matcherOut, xml );
+ } else {
+ push.apply( results, matcherOut );
+ }
+ }
+ });
+}
+
+function matcherFromTokens( tokens ) {
+ var checkContext, matcher, j,
+ len = tokens.length,
+ leadingRelative = Expr.relative[ tokens[0].type ],
+ implicitRelative = leadingRelative || Expr.relative[" "],
+ i = leadingRelative ? 1 : 0,
+
+ // The foundational matcher ensures that elements are reachable from top-level context(s)
+ matchContext = addCombinator( function( elem ) {
+ return elem === checkContext;
+ }, implicitRelative, true ),
+ matchAnyContext = addCombinator( function( elem ) {
+ return indexOf( checkContext, elem ) > -1;
+ }, implicitRelative, true ),
+ matchers = [ function( elem, context, xml ) {
+ var ret = ( !leadingRelative && ( xml || context !== outermostContext ) ) || (
+ (checkContext = context).nodeType ?
+ matchContext( elem, context, xml ) :
+ matchAnyContext( elem, context, xml ) );
+ // Avoid hanging onto element (issue #299)
+ checkContext = null;
+ return ret;
+ } ];
+
+ for ( ; i < len; i++ ) {
+ if ( (matcher = Expr.relative[ tokens[i].type ]) ) {
+ matchers = [ addCombinator(elementMatcher( matchers ), matcher) ];
+ } else {
+ matcher = Expr.filter[ tokens[i].type ].apply( null, tokens[i].matches );
+
+ // Return special upon seeing a positional matcher
+ if ( matcher[ expando ] ) {
+ // Find the next relative operator (if any) for proper handling
+ j = ++i;
+ for ( ; j < len; j++ ) {
+ if ( Expr.relative[ tokens[j].type ] ) {
+ break;
+ }
+ }
+ return setMatcher(
+ i > 1 && elementMatcher( matchers ),
+ i > 1 && toSelector(
+ // If the preceding token was a descendant combinator, insert an implicit any-element `*`
+ tokens.slice( 0, i - 1 ).concat({ value: tokens[ i - 2 ].type === " " ? "*" : "" })
+ ).replace( rtrim, "$1" ),
+ matcher,
+ i < j && matcherFromTokens( tokens.slice( i, j ) ),
+ j < len && matcherFromTokens( (tokens = tokens.slice( j )) ),
+ j < len && toSelector( tokens )
+ );
+ }
+ matchers.push( matcher );
+ }
+ }
+
+ return elementMatcher( matchers );
+}
+
+function matcherFromGroupMatchers( elementMatchers, setMatchers ) {
+ var bySet = setMatchers.length > 0,
+ byElement = elementMatchers.length > 0,
+ superMatcher = function( seed, context, xml, results, outermost ) {
+ var elem, j, matcher,
+ matchedCount = 0,
+ i = "0",
+ unmatched = seed && [],
+ setMatched = [],
+ contextBackup = outermostContext,
+ // We must always have either seed elements or outermost context
+ elems = seed || byElement && Expr.find["TAG"]( "*", outermost ),
+ // Use integer dirruns iff this is the outermost matcher
+ dirrunsUnique = (dirruns += contextBackup == null ? 1 : Math.random() || 0.1),
+ len = elems.length;
+
+ if ( outermost ) {
+ outermostContext = context === document || context || outermost;
+ }
+
+ // Add elements passing elementMatchers directly to results
+ // Support: IE<9, Safari
+ // Tolerate NodeList properties (IE: "length"; Safari: ) matching elements by id
+ for ( ; i !== len && (elem = elems[i]) != null; i++ ) {
+ if ( byElement && elem ) {
+ j = 0;
+ if ( !context && elem.ownerDocument !== document ) {
+ setDocument( elem );
+ xml = !documentIsHTML;
+ }
+ while ( (matcher = elementMatchers[j++]) ) {
+ if ( matcher( elem, context || document, xml) ) {
+ results.push( elem );
+ break;
+ }
+ }
+ if ( outermost ) {
+ dirruns = dirrunsUnique;
+ }
+ }
+
+ // Track unmatched elements for set filters
+ if ( bySet ) {
+ // They will have gone through all possible matchers
+ if ( (elem = !matcher && elem) ) {
+ matchedCount--;
+ }
+
+ // Lengthen the array for every element, matched or not
+ if ( seed ) {
+ unmatched.push( elem );
+ }
+ }
+ }
+
+ // `i` is now the count of elements visited above, and adding it to `matchedCount`
+ // makes the latter nonnegative.
+ matchedCount += i;
+
+ // Apply set filters to unmatched elements
+ // NOTE: This can be skipped if there are no unmatched elements (i.e., `matchedCount`
+ // equals `i`), unless we didn't visit _any_ elements in the above loop because we have
+ // no element matchers and no seed.
+ // Incrementing an initially-string "0" `i` allows `i` to remain a string only in that
+ // case, which will result in a "00" `matchedCount` that differs from `i` but is also
+ // numerically zero.
+ if ( bySet && i !== matchedCount ) {
+ j = 0;
+ while ( (matcher = setMatchers[j++]) ) {
+ matcher( unmatched, setMatched, context, xml );
+ }
+
+ if ( seed ) {
+ // Reintegrate element matches to eliminate the need for sorting
+ if ( matchedCount > 0 ) {
+ while ( i-- ) {
+ if ( !(unmatched[i] || setMatched[i]) ) {
+ setMatched[i] = pop.call( results );
+ }
+ }
+ }
+
+ // Discard index placeholder values to get only actual matches
+ setMatched = condense( setMatched );
+ }
+
+ // Add matches to results
+ push.apply( results, setMatched );
+
+ // Seedless set matches succeeding multiple successful matchers stipulate sorting
+ if ( outermost && !seed && setMatched.length > 0 &&
+ ( matchedCount + setMatchers.length ) > 1 ) {
+
+ Sizzle.uniqueSort( results );
+ }
+ }
+
+ // Override manipulation of globals by nested matchers
+ if ( outermost ) {
+ dirruns = dirrunsUnique;
+ outermostContext = contextBackup;
+ }
+
+ return unmatched;
+ };
+
+ return bySet ?
+ markFunction( superMatcher ) :
+ superMatcher;
+}
+
+compile = Sizzle.compile = function( selector, match /* Internal Use Only */ ) {
+ var i,
+ setMatchers = [],
+ elementMatchers = [],
+ cached = compilerCache[ selector + " " ];
+
+ if ( !cached ) {
+ // Generate a function of recursive functions that can be used to check each element
+ if ( !match ) {
+ match = tokenize( selector );
+ }
+ i = match.length;
+ while ( i-- ) {
+ cached = matcherFromTokens( match[i] );
+ if ( cached[ expando ] ) {
+ setMatchers.push( cached );
+ } else {
+ elementMatchers.push( cached );
+ }
+ }
+
+ // Cache the compiled function
+ cached = compilerCache( selector, matcherFromGroupMatchers( elementMatchers, setMatchers ) );
+
+ // Save selector and tokenization
+ cached.selector = selector;
+ }
+ return cached;
+};
+
+/**
+ * A low-level selection function that works with Sizzle's compiled
+ * selector functions
+ * @param {String|Function} selector A selector or a pre-compiled
+ * selector function built with Sizzle.compile
+ * @param {Element} context
+ * @param {Array} [results]
+ * @param {Array} [seed] A set of elements to match against
+ */
+select = Sizzle.select = function( selector, context, results, seed ) {
+ var i, tokens, token, type, find,
+ compiled = typeof selector === "function" && selector,
+ match = !seed && tokenize( (selector = compiled.selector || selector) );
+
+ results = results || [];
+
+ // Try to minimize operations if there is only one selector in the list and no seed
+ // (the latter of which guarantees us context)
+ if ( match.length === 1 ) {
+
+ // Reduce context if the leading compound selector is an ID
+ tokens = match[0] = match[0].slice( 0 );
+ if ( tokens.length > 2 && (token = tokens[0]).type === "ID" &&
+ support.getById && context.nodeType === 9 && documentIsHTML &&
+ Expr.relative[ tokens[1].type ] ) {
+
+ context = ( Expr.find["ID"]( token.matches[0].replace(runescape, funescape), context ) || [] )[0];
+ if ( !context ) {
+ return results;
+
+ // Precompiled matchers will still verify ancestry, so step up a level
+ } else if ( compiled ) {
+ context = context.parentNode;
+ }
+
+ selector = selector.slice( tokens.shift().value.length );
+ }
+
+ // Fetch a seed set for right-to-left matching
+ i = matchExpr["needsContext"].test( selector ) ? 0 : tokens.length;
+ while ( i-- ) {
+ token = tokens[i];
+
+ // Abort if we hit a combinator
+ if ( Expr.relative[ (type = token.type) ] ) {
+ break;
+ }
+ if ( (find = Expr.find[ type ]) ) {
+ // Search, expanding context for leading sibling combinators
+ if ( (seed = find(
+ token.matches[0].replace( runescape, funescape ),
+ rsibling.test( tokens[0].type ) && testContext( context.parentNode ) || context
+ )) ) {
+
+ // If seed is empty or no tokens remain, we can return early
+ tokens.splice( i, 1 );
+ selector = seed.length && toSelector( tokens );
+ if ( !selector ) {
+ push.apply( results, seed );
+ return results;
+ }
+
+ break;
+ }
+ }
+ }
+ }
+
+ // Compile and execute a filtering function if one is not provided
+ // Provide `match` to avoid retokenization if we modified the selector above
+ ( compiled || compile( selector, match ) )(
+ seed,
+ context,
+ !documentIsHTML,
+ results,
+ !context || rsibling.test( selector ) && testContext( context.parentNode ) || context
+ );
+ return results;
+};
+
+// One-time assignments
+
+// Sort stability
+support.sortStable = expando.split("").sort( sortOrder ).join("") === expando;
+
+// Support: Chrome 14-35+
+// Always assume duplicates if they aren't passed to the comparison function
+support.detectDuplicates = !!hasDuplicate;
+
+// Initialize against the default document
+setDocument();
+
+// Support: Webkit<537.32 - Safari 6.0.3/Chrome 25 (fixed in Chrome 27)
+// Detached nodes confoundingly follow *each other*
+support.sortDetached = assert(function( div1 ) {
+ // Should return 1, but returns 4 (following)
+ return div1.compareDocumentPosition( document.createElement("div") ) & 1;
+});
+
+// Support: IE<8
+// Prevent attribute/property "interpolation"
+// http://msdn.microsoft.com/en-us/library/ms536429%28VS.85%29.aspx
+if ( !assert(function( div ) {
+ div.innerHTML = "";
+ return div.firstChild.getAttribute("href") === "#" ;
+}) ) {
+ addHandle( "type|href|height|width", function( elem, name, isXML ) {
+ if ( !isXML ) {
+ return elem.getAttribute( name, name.toLowerCase() === "type" ? 1 : 2 );
+ }
+ });
+}
+
+// Support: IE<9
+// Use defaultValue in place of getAttribute("value")
+if ( !support.attributes || !assert(function( div ) {
+ div.innerHTML = "";
+ div.firstChild.setAttribute( "value", "" );
+ return div.firstChild.getAttribute( "value" ) === "";
+}) ) {
+ addHandle( "value", function( elem, name, isXML ) {
+ if ( !isXML && elem.nodeName.toLowerCase() === "input" ) {
+ return elem.defaultValue;
+ }
+ });
+}
+
+// Support: IE<9
+// Use getAttributeNode to fetch booleans when getAttribute lies
+if ( !assert(function( div ) {
+ return div.getAttribute("disabled") == null;
+}) ) {
+ addHandle( booleans, function( elem, name, isXML ) {
+ var val;
+ if ( !isXML ) {
+ return elem[ name ] === true ? name.toLowerCase() :
+ (val = elem.getAttributeNode( name )) && val.specified ?
+ val.value :
+ null;
+ }
+ });
+}
+
+return Sizzle;
+
+})( window );
+
+
+
+jQuery.find = Sizzle;
+jQuery.expr = Sizzle.selectors;
+jQuery.expr[ ":" ] = jQuery.expr.pseudos;
+jQuery.uniqueSort = jQuery.unique = Sizzle.uniqueSort;
+jQuery.text = Sizzle.getText;
+jQuery.isXMLDoc = Sizzle.isXML;
+jQuery.contains = Sizzle.contains;
+
+
+
+var dir = function( elem, dir, until ) {
+ var matched = [],
+ truncate = until !== undefined;
+
+ while ( ( elem = elem[ dir ] ) && elem.nodeType !== 9 ) {
+ if ( elem.nodeType === 1 ) {
+ if ( truncate && jQuery( elem ).is( until ) ) {
+ break;
+ }
+ matched.push( elem );
+ }
+ }
+ return matched;
+};
+
+
+var siblings = function( n, elem ) {
+ var matched = [];
+
+ for ( ; n; n = n.nextSibling ) {
+ if ( n.nodeType === 1 && n !== elem ) {
+ matched.push( n );
+ }
+ }
+
+ return matched;
+};
+
+
+var rneedsContext = jQuery.expr.match.needsContext;
+
+var rsingleTag = ( /^<([\w-]+)\s*\/?>(?:<\/\1>|)$/ );
+
+
+
+var risSimple = /^.[^:#\[\.,]*$/;
+
+// Implement the identical functionality for filter and not
+function winnow( elements, qualifier, not ) {
+ if ( jQuery.isFunction( qualifier ) ) {
+ return jQuery.grep( elements, function( elem, i ) {
+ /* jshint -W018 */
+ return !!qualifier.call( elem, i, elem ) !== not;
+ } );
+
+ }
+
+ if ( qualifier.nodeType ) {
+ return jQuery.grep( elements, function( elem ) {
+ return ( elem === qualifier ) !== not;
+ } );
+
+ }
+
+ if ( typeof qualifier === "string" ) {
+ if ( risSimple.test( qualifier ) ) {
+ return jQuery.filter( qualifier, elements, not );
+ }
+
+ qualifier = jQuery.filter( qualifier, elements );
+ }
+
+ return jQuery.grep( elements, function( elem ) {
+ return ( indexOf.call( qualifier, elem ) > -1 ) !== not;
+ } );
+}
+
+jQuery.filter = function( expr, elems, not ) {
+ var elem = elems[ 0 ];
+
+ if ( not ) {
+ expr = ":not(" + expr + ")";
+ }
+
+ return elems.length === 1 && elem.nodeType === 1 ?
+ jQuery.find.matchesSelector( elem, expr ) ? [ elem ] : [] :
+ jQuery.find.matches( expr, jQuery.grep( elems, function( elem ) {
+ return elem.nodeType === 1;
+ } ) );
+};
+
+jQuery.fn.extend( {
+ find: function( selector ) {
+ var i,
+ len = this.length,
+ ret = [],
+ self = this;
+
+ if ( typeof selector !== "string" ) {
+ return this.pushStack( jQuery( selector ).filter( function() {
+ for ( i = 0; i < len; i++ ) {
+ if ( jQuery.contains( self[ i ], this ) ) {
+ return true;
+ }
+ }
+ } ) );
+ }
+
+ for ( i = 0; i < len; i++ ) {
+ jQuery.find( selector, self[ i ], ret );
+ }
+
+ // Needed because $( selector, context ) becomes $( context ).find( selector )
+ ret = this.pushStack( len > 1 ? jQuery.unique( ret ) : ret );
+ ret.selector = this.selector ? this.selector + " " + selector : selector;
+ return ret;
+ },
+ filter: function( selector ) {
+ return this.pushStack( winnow( this, selector || [], false ) );
+ },
+ not: function( selector ) {
+ return this.pushStack( winnow( this, selector || [], true ) );
+ },
+ is: function( selector ) {
+ return !!winnow(
+ this,
+
+ // If this is a positional/relative selector, check membership in the returned set
+ // so $("p:first").is("p:last") won't return true for a doc with two "p".
+ typeof selector === "string" && rneedsContext.test( selector ) ?
+ jQuery( selector ) :
+ selector || [],
+ false
+ ).length;
+ }
+} );
+
+
+// Initialize a jQuery object
+
+
+// A central reference to the root jQuery(document)
+var rootjQuery,
+
+ // A simple way to check for HTML strings
+ // Prioritize #id over to avoid XSS via location.hash (#9521)
+ // Strict HTML recognition (#11290: must start with <)
+ rquickExpr = /^(?:\s*(<[\w\W]+>)[^>]*|#([\w-]*))$/,
+
+ init = jQuery.fn.init = function( selector, context, root ) {
+ var match, elem;
+
+ // HANDLE: $(""), $(null), $(undefined), $(false)
+ if ( !selector ) {
+ return this;
+ }
+
+ // Method init() accepts an alternate rootjQuery
+ // so migrate can support jQuery.sub (gh-2101)
+ root = root || rootjQuery;
+
+ // Handle HTML strings
+ if ( typeof selector === "string" ) {
+ if ( selector[ 0 ] === "<" &&
+ selector[ selector.length - 1 ] === ">" &&
+ selector.length >= 3 ) {
+
+ // Assume that strings that start and end with <> are HTML and skip the regex check
+ match = [ null, selector, null ];
+
+ } else {
+ match = rquickExpr.exec( selector );
+ }
+
+ // Match html or make sure no context is specified for #id
+ if ( match && ( match[ 1 ] || !context ) ) {
+
+ // HANDLE: $(html) -> $(array)
+ if ( match[ 1 ] ) {
+ context = context instanceof jQuery ? context[ 0 ] : context;
+
+ // Option to run scripts is true for back-compat
+ // Intentionally let the error be thrown if parseHTML is not present
+ jQuery.merge( this, jQuery.parseHTML(
+ match[ 1 ],
+ context && context.nodeType ? context.ownerDocument || context : document,
+ true
+ ) );
+
+ // HANDLE: $(html, props)
+ if ( rsingleTag.test( match[ 1 ] ) && jQuery.isPlainObject( context ) ) {
+ for ( match in context ) {
+
+ // Properties of context are called as methods if possible
+ if ( jQuery.isFunction( this[ match ] ) ) {
+ this[ match ]( context[ match ] );
+
+ // ...and otherwise set as attributes
+ } else {
+ this.attr( match, context[ match ] );
+ }
+ }
+ }
+
+ return this;
+
+ // HANDLE: $(#id)
+ } else {
+ elem = document.getElementById( match[ 2 ] );
+
+ // Support: Blackberry 4.6
+ // gEBID returns nodes no longer in the document (#6963)
+ if ( elem && elem.parentNode ) {
+
+ // Inject the element directly into the jQuery object
+ this.length = 1;
+ this[ 0 ] = elem;
+ }
+
+ this.context = document;
+ this.selector = selector;
+ return this;
+ }
+
+ // HANDLE: $(expr, $(...))
+ } else if ( !context || context.jquery ) {
+ return ( context || root ).find( selector );
+
+ // HANDLE: $(expr, context)
+ // (which is just equivalent to: $(context).find(expr)
+ } else {
+ return this.constructor( context ).find( selector );
+ }
+
+ // HANDLE: $(DOMElement)
+ } else if ( selector.nodeType ) {
+ this.context = this[ 0 ] = selector;
+ this.length = 1;
+ return this;
+
+ // HANDLE: $(function)
+ // Shortcut for document ready
+ } else if ( jQuery.isFunction( selector ) ) {
+ return root.ready !== undefined ?
+ root.ready( selector ) :
+
+ // Execute immediately if ready is not present
+ selector( jQuery );
+ }
+
+ if ( selector.selector !== undefined ) {
+ this.selector = selector.selector;
+ this.context = selector.context;
+ }
+
+ return jQuery.makeArray( selector, this );
+ };
+
+// Give the init function the jQuery prototype for later instantiation
+init.prototype = jQuery.fn;
+
+// Initialize central reference
+rootjQuery = jQuery( document );
+
+
+var rparentsprev = /^(?:parents|prev(?:Until|All))/,
+
+ // Methods guaranteed to produce a unique set when starting from a unique set
+ guaranteedUnique = {
+ children: true,
+ contents: true,
+ next: true,
+ prev: true
+ };
+
+jQuery.fn.extend( {
+ has: function( target ) {
+ var targets = jQuery( target, this ),
+ l = targets.length;
+
+ return this.filter( function() {
+ var i = 0;
+ for ( ; i < l; i++ ) {
+ if ( jQuery.contains( this, targets[ i ] ) ) {
+ return true;
+ }
+ }
+ } );
+ },
+
+ closest: function( selectors, context ) {
+ var cur,
+ i = 0,
+ l = this.length,
+ matched = [],
+ pos = rneedsContext.test( selectors ) || typeof selectors !== "string" ?
+ jQuery( selectors, context || this.context ) :
+ 0;
+
+ for ( ; i < l; i++ ) {
+ for ( cur = this[ i ]; cur && cur !== context; cur = cur.parentNode ) {
+
+ // Always skip document fragments
+ if ( cur.nodeType < 11 && ( pos ?
+ pos.index( cur ) > -1 :
+
+ // Don't pass non-elements to Sizzle
+ cur.nodeType === 1 &&
+ jQuery.find.matchesSelector( cur, selectors ) ) ) {
+
+ matched.push( cur );
+ break;
+ }
+ }
+ }
+
+ return this.pushStack( matched.length > 1 ? jQuery.uniqueSort( matched ) : matched );
+ },
+
+ // Determine the position of an element within the set
+ index: function( elem ) {
+
+ // No argument, return index in parent
+ if ( !elem ) {
+ return ( this[ 0 ] && this[ 0 ].parentNode ) ? this.first().prevAll().length : -1;
+ }
+
+ // Index in selector
+ if ( typeof elem === "string" ) {
+ return indexOf.call( jQuery( elem ), this[ 0 ] );
+ }
+
+ // Locate the position of the desired element
+ return indexOf.call( this,
+
+ // If it receives a jQuery object, the first element is used
+ elem.jquery ? elem[ 0 ] : elem
+ );
+ },
+
+ add: function( selector, context ) {
+ return this.pushStack(
+ jQuery.uniqueSort(
+ jQuery.merge( this.get(), jQuery( selector, context ) )
+ )
+ );
+ },
+
+ addBack: function( selector ) {
+ return this.add( selector == null ?
+ this.prevObject : this.prevObject.filter( selector )
+ );
+ }
+} );
+
+function sibling( cur, dir ) {
+ while ( ( cur = cur[ dir ] ) && cur.nodeType !== 1 ) {}
+ return cur;
+}
+
+jQuery.each( {
+ parent: function( elem ) {
+ var parent = elem.parentNode;
+ return parent && parent.nodeType !== 11 ? parent : null;
+ },
+ parents: function( elem ) {
+ return dir( elem, "parentNode" );
+ },
+ parentsUntil: function( elem, i, until ) {
+ return dir( elem, "parentNode", until );
+ },
+ next: function( elem ) {
+ return sibling( elem, "nextSibling" );
+ },
+ prev: function( elem ) {
+ return sibling( elem, "previousSibling" );
+ },
+ nextAll: function( elem ) {
+ return dir( elem, "nextSibling" );
+ },
+ prevAll: function( elem ) {
+ return dir( elem, "previousSibling" );
+ },
+ nextUntil: function( elem, i, until ) {
+ return dir( elem, "nextSibling", until );
+ },
+ prevUntil: function( elem, i, until ) {
+ return dir( elem, "previousSibling", until );
+ },
+ siblings: function( elem ) {
+ return siblings( ( elem.parentNode || {} ).firstChild, elem );
+ },
+ children: function( elem ) {
+ return siblings( elem.firstChild );
+ },
+ contents: function( elem ) {
+ return elem.contentDocument || jQuery.merge( [], elem.childNodes );
+ }
+}, function( name, fn ) {
+ jQuery.fn[ name ] = function( until, selector ) {
+ var matched = jQuery.map( this, fn, until );
+
+ if ( name.slice( -5 ) !== "Until" ) {
+ selector = until;
+ }
+
+ if ( selector && typeof selector === "string" ) {
+ matched = jQuery.filter( selector, matched );
+ }
+
+ if ( this.length > 1 ) {
+
+ // Remove duplicates
+ if ( !guaranteedUnique[ name ] ) {
+ jQuery.uniqueSort( matched );
+ }
+
+ // Reverse order for parents* and prev-derivatives
+ if ( rparentsprev.test( name ) ) {
+ matched.reverse();
+ }
+ }
+
+ return this.pushStack( matched );
+ };
+} );
+var rnotwhite = ( /\S+/g );
+
+
+
+// Convert String-formatted options into Object-formatted ones
+function createOptions( options ) {
+ var object = {};
+ jQuery.each( options.match( rnotwhite ) || [], function( _, flag ) {
+ object[ flag ] = true;
+ } );
+ return object;
+}
+
+/*
+ * Create a callback list using the following parameters:
+ *
+ * options: an optional list of space-separated options that will change how
+ * the callback list behaves or a more traditional option object
+ *
+ * By default a callback list will act like an event callback list and can be
+ * "fired" multiple times.
+ *
+ * Possible options:
+ *
+ * once: will ensure the callback list can only be fired once (like a Deferred)
+ *
+ * memory: will keep track of previous values and will call any callback added
+ * after the list has been fired right away with the latest "memorized"
+ * values (like a Deferred)
+ *
+ * unique: will ensure a callback can only be added once (no duplicate in the list)
+ *
+ * stopOnFalse: interrupt callings when a callback returns false
+ *
+ */
+jQuery.Callbacks = function( options ) {
+
+ // Convert options from String-formatted to Object-formatted if needed
+ // (we check in cache first)
+ options = typeof options === "string" ?
+ createOptions( options ) :
+ jQuery.extend( {}, options );
+
+ var // Flag to know if list is currently firing
+ firing,
+
+ // Last fire value for non-forgettable lists
+ memory,
+
+ // Flag to know if list was already fired
+ fired,
+
+ // Flag to prevent firing
+ locked,
+
+ // Actual callback list
+ list = [],
+
+ // Queue of execution data for repeatable lists
+ queue = [],
+
+ // Index of currently firing callback (modified by add/remove as needed)
+ firingIndex = -1,
+
+ // Fire callbacks
+ fire = function() {
+
+ // Enforce single-firing
+ locked = options.once;
+
+ // Execute callbacks for all pending executions,
+ // respecting firingIndex overrides and runtime changes
+ fired = firing = true;
+ for ( ; queue.length; firingIndex = -1 ) {
+ memory = queue.shift();
+ while ( ++firingIndex < list.length ) {
+
+ // Run callback and check for early termination
+ if ( list[ firingIndex ].apply( memory[ 0 ], memory[ 1 ] ) === false &&
+ options.stopOnFalse ) {
+
+ // Jump to end and forget the data so .add doesn't re-fire
+ firingIndex = list.length;
+ memory = false;
+ }
+ }
+ }
+
+ // Forget the data if we're done with it
+ if ( !options.memory ) {
+ memory = false;
+ }
+
+ firing = false;
+
+ // Clean up if we're done firing for good
+ if ( locked ) {
+
+ // Keep an empty list if we have data for future add calls
+ if ( memory ) {
+ list = [];
+
+ // Otherwise, this object is spent
+ } else {
+ list = "";
+ }
+ }
+ },
+
+ // Actual Callbacks object
+ self = {
+
+ // Add a callback or a collection of callbacks to the list
+ add: function() {
+ if ( list ) {
+
+ // If we have memory from a past run, we should fire after adding
+ if ( memory && !firing ) {
+ firingIndex = list.length - 1;
+ queue.push( memory );
+ }
+
+ ( function add( args ) {
+ jQuery.each( args, function( _, arg ) {
+ if ( jQuery.isFunction( arg ) ) {
+ if ( !options.unique || !self.has( arg ) ) {
+ list.push( arg );
+ }
+ } else if ( arg && arg.length && jQuery.type( arg ) !== "string" ) {
+
+ // Inspect recursively
+ add( arg );
+ }
+ } );
+ } )( arguments );
+
+ if ( memory && !firing ) {
+ fire();
+ }
+ }
+ return this;
+ },
+
+ // Remove a callback from the list
+ remove: function() {
+ jQuery.each( arguments, function( _, arg ) {
+ var index;
+ while ( ( index = jQuery.inArray( arg, list, index ) ) > -1 ) {
+ list.splice( index, 1 );
+
+ // Handle firing indexes
+ if ( index <= firingIndex ) {
+ firingIndex--;
+ }
+ }
+ } );
+ return this;
+ },
+
+ // Check if a given callback is in the list.
+ // If no argument is given, return whether or not list has callbacks attached.
+ has: function( fn ) {
+ return fn ?
+ jQuery.inArray( fn, list ) > -1 :
+ list.length > 0;
+ },
+
+ // Remove all callbacks from the list
+ empty: function() {
+ if ( list ) {
+ list = [];
+ }
+ return this;
+ },
+
+ // Disable .fire and .add
+ // Abort any current/pending executions
+ // Clear all callbacks and values
+ disable: function() {
+ locked = queue = [];
+ list = memory = "";
+ return this;
+ },
+ disabled: function() {
+ return !list;
+ },
+
+ // Disable .fire
+ // Also disable .add unless we have memory (since it would have no effect)
+ // Abort any pending executions
+ lock: function() {
+ locked = queue = [];
+ if ( !memory ) {
+ list = memory = "";
+ }
+ return this;
+ },
+ locked: function() {
+ return !!locked;
+ },
+
+ // Call all callbacks with the given context and arguments
+ fireWith: function( context, args ) {
+ if ( !locked ) {
+ args = args || [];
+ args = [ context, args.slice ? args.slice() : args ];
+ queue.push( args );
+ if ( !firing ) {
+ fire();
+ }
+ }
+ return this;
+ },
+
+ // Call all the callbacks with the given arguments
+ fire: function() {
+ self.fireWith( this, arguments );
+ return this;
+ },
+
+ // To know if the callbacks have already been called at least once
+ fired: function() {
+ return !!fired;
+ }
+ };
+
+ return self;
+};
+
+
+jQuery.extend( {
+
+ Deferred: function( func ) {
+ var tuples = [
+
+ // action, add listener, listener list, final state
+ [ "resolve", "done", jQuery.Callbacks( "once memory" ), "resolved" ],
+ [ "reject", "fail", jQuery.Callbacks( "once memory" ), "rejected" ],
+ [ "notify", "progress", jQuery.Callbacks( "memory" ) ]
+ ],
+ state = "pending",
+ promise = {
+ state: function() {
+ return state;
+ },
+ always: function() {
+ deferred.done( arguments ).fail( arguments );
+ return this;
+ },
+ then: function( /* fnDone, fnFail, fnProgress */ ) {
+ var fns = arguments;
+ return jQuery.Deferred( function( newDefer ) {
+ jQuery.each( tuples, function( i, tuple ) {
+ var fn = jQuery.isFunction( fns[ i ] ) && fns[ i ];
+
+ // deferred[ done | fail | progress ] for forwarding actions to newDefer
+ deferred[ tuple[ 1 ] ]( function() {
+ var returned = fn && fn.apply( this, arguments );
+ if ( returned && jQuery.isFunction( returned.promise ) ) {
+ returned.promise()
+ .progress( newDefer.notify )
+ .done( newDefer.resolve )
+ .fail( newDefer.reject );
+ } else {
+ newDefer[ tuple[ 0 ] + "With" ](
+ this === promise ? newDefer.promise() : this,
+ fn ? [ returned ] : arguments
+ );
+ }
+ } );
+ } );
+ fns = null;
+ } ).promise();
+ },
+
+ // Get a promise for this deferred
+ // If obj is provided, the promise aspect is added to the object
+ promise: function( obj ) {
+ return obj != null ? jQuery.extend( obj, promise ) : promise;
+ }
+ },
+ deferred = {};
+
+ // Keep pipe for back-compat
+ promise.pipe = promise.then;
+
+ // Add list-specific methods
+ jQuery.each( tuples, function( i, tuple ) {
+ var list = tuple[ 2 ],
+ stateString = tuple[ 3 ];
+
+ // promise[ done | fail | progress ] = list.add
+ promise[ tuple[ 1 ] ] = list.add;
+
+ // Handle state
+ if ( stateString ) {
+ list.add( function() {
+
+ // state = [ resolved | rejected ]
+ state = stateString;
+
+ // [ reject_list | resolve_list ].disable; progress_list.lock
+ }, tuples[ i ^ 1 ][ 2 ].disable, tuples[ 2 ][ 2 ].lock );
+ }
+
+ // deferred[ resolve | reject | notify ]
+ deferred[ tuple[ 0 ] ] = function() {
+ deferred[ tuple[ 0 ] + "With" ]( this === deferred ? promise : this, arguments );
+ return this;
+ };
+ deferred[ tuple[ 0 ] + "With" ] = list.fireWith;
+ } );
+
+ // Make the deferred a promise
+ promise.promise( deferred );
+
+ // Call given func if any
+ if ( func ) {
+ func.call( deferred, deferred );
+ }
+
+ // All done!
+ return deferred;
+ },
+
+ // Deferred helper
+ when: function( subordinate /* , ..., subordinateN */ ) {
+ var i = 0,
+ resolveValues = slice.call( arguments ),
+ length = resolveValues.length,
+
+ // the count of uncompleted subordinates
+ remaining = length !== 1 ||
+ ( subordinate && jQuery.isFunction( subordinate.promise ) ) ? length : 0,
+
+ // the master Deferred.
+ // If resolveValues consist of only a single Deferred, just use that.
+ deferred = remaining === 1 ? subordinate : jQuery.Deferred(),
+
+ // Update function for both resolve and progress values
+ updateFunc = function( i, contexts, values ) {
+ return function( value ) {
+ contexts[ i ] = this;
+ values[ i ] = arguments.length > 1 ? slice.call( arguments ) : value;
+ if ( values === progressValues ) {
+ deferred.notifyWith( contexts, values );
+ } else if ( !( --remaining ) ) {
+ deferred.resolveWith( contexts, values );
+ }
+ };
+ },
+
+ progressValues, progressContexts, resolveContexts;
+
+ // Add listeners to Deferred subordinates; treat others as resolved
+ if ( length > 1 ) {
+ progressValues = new Array( length );
+ progressContexts = new Array( length );
+ resolveContexts = new Array( length );
+ for ( ; i < length; i++ ) {
+ if ( resolveValues[ i ] && jQuery.isFunction( resolveValues[ i ].promise ) ) {
+ resolveValues[ i ].promise()
+ .progress( updateFunc( i, progressContexts, progressValues ) )
+ .done( updateFunc( i, resolveContexts, resolveValues ) )
+ .fail( deferred.reject );
+ } else {
+ --remaining;
+ }
+ }
+ }
+
+ // If we're not waiting on anything, resolve the master
+ if ( !remaining ) {
+ deferred.resolveWith( resolveContexts, resolveValues );
+ }
+
+ return deferred.promise();
+ }
+} );
+
+
+// The deferred used on DOM ready
+var readyList;
+
+jQuery.fn.ready = function( fn ) {
+
+ // Add the callback
+ jQuery.ready.promise().done( fn );
+
+ return this;
+};
+
+jQuery.extend( {
+
+ // Is the DOM ready to be used? Set to true once it occurs.
+ isReady: false,
+
+ // A counter to track how many items to wait for before
+ // the ready event fires. See #6781
+ readyWait: 1,
+
+ // Hold (or release) the ready event
+ holdReady: function( hold ) {
+ if ( hold ) {
+ jQuery.readyWait++;
+ } else {
+ jQuery.ready( true );
+ }
+ },
+
+ // Handle when the DOM is ready
+ ready: function( wait ) {
+
+ // Abort if there are pending holds or we're already ready
+ if ( wait === true ? --jQuery.readyWait : jQuery.isReady ) {
+ return;
+ }
+
+ // Remember that the DOM is ready
+ jQuery.isReady = true;
+
+ // If a normal DOM Ready event fired, decrement, and wait if need be
+ if ( wait !== true && --jQuery.readyWait > 0 ) {
+ return;
+ }
+
+ // If there are functions bound, to execute
+ readyList.resolveWith( document, [ jQuery ] );
+
+ // Trigger any bound ready events
+ if ( jQuery.fn.triggerHandler ) {
+ jQuery( document ).triggerHandler( "ready" );
+ jQuery( document ).off( "ready" );
+ }
+ }
+} );
+
+/**
+ * The ready event handler and self cleanup method
+ */
+function completed() {
+ document.removeEventListener( "DOMContentLoaded", completed );
+ window.removeEventListener( "load", completed );
+ jQuery.ready();
+}
+
+jQuery.ready.promise = function( obj ) {
+ if ( !readyList ) {
+
+ readyList = jQuery.Deferred();
+
+ // Catch cases where $(document).ready() is called
+ // after the browser event has already occurred.
+ // Support: IE9-10 only
+ // Older IE sometimes signals "interactive" too soon
+ if ( document.readyState === "complete" ||
+ ( document.readyState !== "loading" && !document.documentElement.doScroll ) ) {
+
+ // Handle it asynchronously to allow scripts the opportunity to delay ready
+ window.setTimeout( jQuery.ready );
+
+ } else {
+
+ // Use the handy event callback
+ document.addEventListener( "DOMContentLoaded", completed );
+
+ // A fallback to window.onload, that will always work
+ window.addEventListener( "load", completed );
+ }
+ }
+ return readyList.promise( obj );
+};
+
+// Kick off the DOM ready check even if the user does not
+jQuery.ready.promise();
+
+
+
+
+// Multifunctional method to get and set values of a collection
+// The value/s can optionally be executed if it's a function
+var access = function( elems, fn, key, value, chainable, emptyGet, raw ) {
+ var i = 0,
+ len = elems.length,
+ bulk = key == null;
+
+ // Sets many values
+ if ( jQuery.type( key ) === "object" ) {
+ chainable = true;
+ for ( i in key ) {
+ access( elems, fn, i, key[ i ], true, emptyGet, raw );
+ }
+
+ // Sets one value
+ } else if ( value !== undefined ) {
+ chainable = true;
+
+ if ( !jQuery.isFunction( value ) ) {
+ raw = true;
+ }
+
+ if ( bulk ) {
+
+ // Bulk operations run against the entire set
+ if ( raw ) {
+ fn.call( elems, value );
+ fn = null;
+
+ // ...except when executing function values
+ } else {
+ bulk = fn;
+ fn = function( elem, key, value ) {
+ return bulk.call( jQuery( elem ), value );
+ };
+ }
+ }
+
+ if ( fn ) {
+ for ( ; i < len; i++ ) {
+ fn(
+ elems[ i ], key, raw ?
+ value :
+ value.call( elems[ i ], i, fn( elems[ i ], key ) )
+ );
+ }
+ }
+ }
+
+ return chainable ?
+ elems :
+
+ // Gets
+ bulk ?
+ fn.call( elems ) :
+ len ? fn( elems[ 0 ], key ) : emptyGet;
+};
+var acceptData = function( owner ) {
+
+ // Accepts only:
+ // - Node
+ // - Node.ELEMENT_NODE
+ // - Node.DOCUMENT_NODE
+ // - Object
+ // - Any
+ /* jshint -W018 */
+ return owner.nodeType === 1 || owner.nodeType === 9 || !( +owner.nodeType );
+};
+
+
+
+
+function Data() {
+ this.expando = jQuery.expando + Data.uid++;
+}
+
+Data.uid = 1;
+
+Data.prototype = {
+
+ register: function( owner, initial ) {
+ var value = initial || {};
+
+ // If it is a node unlikely to be stringify-ed or looped over
+ // use plain assignment
+ if ( owner.nodeType ) {
+ owner[ this.expando ] = value;
+
+ // Otherwise secure it in a non-enumerable, non-writable property
+ // configurability must be true to allow the property to be
+ // deleted with the delete operator
+ } else {
+ Object.defineProperty( owner, this.expando, {
+ value: value,
+ writable: true,
+ configurable: true
+ } );
+ }
+ return owner[ this.expando ];
+ },
+ cache: function( owner ) {
+
+ // We can accept data for non-element nodes in modern browsers,
+ // but we should not, see #8335.
+ // Always return an empty object.
+ if ( !acceptData( owner ) ) {
+ return {};
+ }
+
+ // Check if the owner object already has a cache
+ var value = owner[ this.expando ];
+
+ // If not, create one
+ if ( !value ) {
+ value = {};
+
+ // We can accept data for non-element nodes in modern browsers,
+ // but we should not, see #8335.
+ // Always return an empty object.
+ if ( acceptData( owner ) ) {
+
+ // If it is a node unlikely to be stringify-ed or looped over
+ // use plain assignment
+ if ( owner.nodeType ) {
+ owner[ this.expando ] = value;
+
+ // Otherwise secure it in a non-enumerable property
+ // configurable must be true to allow the property to be
+ // deleted when data is removed
+ } else {
+ Object.defineProperty( owner, this.expando, {
+ value: value,
+ configurable: true
+ } );
+ }
+ }
+ }
+
+ return value;
+ },
+ set: function( owner, data, value ) {
+ var prop,
+ cache = this.cache( owner );
+
+ // Handle: [ owner, key, value ] args
+ if ( typeof data === "string" ) {
+ cache[ data ] = value;
+
+ // Handle: [ owner, { properties } ] args
+ } else {
+
+ // Copy the properties one-by-one to the cache object
+ for ( prop in data ) {
+ cache[ prop ] = data[ prop ];
+ }
+ }
+ return cache;
+ },
+ get: function( owner, key ) {
+ return key === undefined ?
+ this.cache( owner ) :
+ owner[ this.expando ] && owner[ this.expando ][ key ];
+ },
+ access: function( owner, key, value ) {
+ var stored;
+
+ // In cases where either:
+ //
+ // 1. No key was specified
+ // 2. A string key was specified, but no value provided
+ //
+ // Take the "read" path and allow the get method to determine
+ // which value to return, respectively either:
+ //
+ // 1. The entire cache object
+ // 2. The data stored at the key
+ //
+ if ( key === undefined ||
+ ( ( key && typeof key === "string" ) && value === undefined ) ) {
+
+ stored = this.get( owner, key );
+
+ return stored !== undefined ?
+ stored : this.get( owner, jQuery.camelCase( key ) );
+ }
+
+ // When the key is not a string, or both a key and value
+ // are specified, set or extend (existing objects) with either:
+ //
+ // 1. An object of properties
+ // 2. A key and value
+ //
+ this.set( owner, key, value );
+
+ // Since the "set" path can have two possible entry points
+ // return the expected data based on which path was taken[*]
+ return value !== undefined ? value : key;
+ },
+ remove: function( owner, key ) {
+ var i, name, camel,
+ cache = owner[ this.expando ];
+
+ if ( cache === undefined ) {
+ return;
+ }
+
+ if ( key === undefined ) {
+ this.register( owner );
+
+ } else {
+
+ // Support array or space separated string of keys
+ if ( jQuery.isArray( key ) ) {
+
+ // If "name" is an array of keys...
+ // When data is initially created, via ("key", "val") signature,
+ // keys will be converted to camelCase.
+ // Since there is no way to tell _how_ a key was added, remove
+ // both plain key and camelCase key. #12786
+ // This will only penalize the array argument path.
+ name = key.concat( key.map( jQuery.camelCase ) );
+ } else {
+ camel = jQuery.camelCase( key );
+
+ // Try the string as a key before any manipulation
+ if ( key in cache ) {
+ name = [ key, camel ];
+ } else {
+
+ // If a key with the spaces exists, use it.
+ // Otherwise, create an array by matching non-whitespace
+ name = camel;
+ name = name in cache ?
+ [ name ] : ( name.match( rnotwhite ) || [] );
+ }
+ }
+
+ i = name.length;
+
+ while ( i-- ) {
+ delete cache[ name[ i ] ];
+ }
+ }
+
+ // Remove the expando if there's no more data
+ if ( key === undefined || jQuery.isEmptyObject( cache ) ) {
+
+ // Support: Chrome <= 35-45+
+ // Webkit & Blink performance suffers when deleting properties
+ // from DOM nodes, so set to undefined instead
+ // https://code.google.com/p/chromium/issues/detail?id=378607
+ if ( owner.nodeType ) {
+ owner[ this.expando ] = undefined;
+ } else {
+ delete owner[ this.expando ];
+ }
+ }
+ },
+ hasData: function( owner ) {
+ var cache = owner[ this.expando ];
+ return cache !== undefined && !jQuery.isEmptyObject( cache );
+ }
+};
+var dataPriv = new Data();
+
+var dataUser = new Data();
+
+
+
+// Implementation Summary
+//
+// 1. Enforce API surface and semantic compatibility with 1.9.x branch
+// 2. Improve the module's maintainability by reducing the storage
+// paths to a single mechanism.
+// 3. Use the same single mechanism to support "private" and "user" data.
+// 4. _Never_ expose "private" data to user code (TODO: Drop _data, _removeData)
+// 5. Avoid exposing implementation details on user objects (eg. expando properties)
+// 6. Provide a clear path for implementation upgrade to WeakMap in 2014
+
+var rbrace = /^(?:\{[\w\W]*\}|\[[\w\W]*\])$/,
+ rmultiDash = /[A-Z]/g;
+
+function dataAttr( elem, key, data ) {
+ var name;
+
+ // If nothing was found internally, try to fetch any
+ // data from the HTML5 data-* attribute
+ if ( data === undefined && elem.nodeType === 1 ) {
+ name = "data-" + key.replace( rmultiDash, "-$&" ).toLowerCase();
+ data = elem.getAttribute( name );
+
+ if ( typeof data === "string" ) {
+ try {
+ data = data === "true" ? true :
+ data === "false" ? false :
+ data === "null" ? null :
+
+ // Only convert to a number if it doesn't change the string
+ +data + "" === data ? +data :
+ rbrace.test( data ) ? jQuery.parseJSON( data ) :
+ data;
+ } catch ( e ) {}
+
+ // Make sure we set the data so it isn't changed later
+ dataUser.set( elem, key, data );
+ } else {
+ data = undefined;
+ }
+ }
+ return data;
+}
+
+jQuery.extend( {
+ hasData: function( elem ) {
+ return dataUser.hasData( elem ) || dataPriv.hasData( elem );
+ },
+
+ data: function( elem, name, data ) {
+ return dataUser.access( elem, name, data );
+ },
+
+ removeData: function( elem, name ) {
+ dataUser.remove( elem, name );
+ },
+
+ // TODO: Now that all calls to _data and _removeData have been replaced
+ // with direct calls to dataPriv methods, these can be deprecated.
+ _data: function( elem, name, data ) {
+ return dataPriv.access( elem, name, data );
+ },
+
+ _removeData: function( elem, name ) {
+ dataPriv.remove( elem, name );
+ }
+} );
+
+jQuery.fn.extend( {
+ data: function( key, value ) {
+ var i, name, data,
+ elem = this[ 0 ],
+ attrs = elem && elem.attributes;
+
+ // Gets all values
+ if ( key === undefined ) {
+ if ( this.length ) {
+ data = dataUser.get( elem );
+
+ if ( elem.nodeType === 1 && !dataPriv.get( elem, "hasDataAttrs" ) ) {
+ i = attrs.length;
+ while ( i-- ) {
+
+ // Support: IE11+
+ // The attrs elements can be null (#14894)
+ if ( attrs[ i ] ) {
+ name = attrs[ i ].name;
+ if ( name.indexOf( "data-" ) === 0 ) {
+ name = jQuery.camelCase( name.slice( 5 ) );
+ dataAttr( elem, name, data[ name ] );
+ }
+ }
+ }
+ dataPriv.set( elem, "hasDataAttrs", true );
+ }
+ }
+
+ return data;
+ }
+
+ // Sets multiple values
+ if ( typeof key === "object" ) {
+ return this.each( function() {
+ dataUser.set( this, key );
+ } );
+ }
+
+ return access( this, function( value ) {
+ var data, camelKey;
+
+ // The calling jQuery object (element matches) is not empty
+ // (and therefore has an element appears at this[ 0 ]) and the
+ // `value` parameter was not undefined. An empty jQuery object
+ // will result in `undefined` for elem = this[ 0 ] which will
+ // throw an exception if an attempt to read a data cache is made.
+ if ( elem && value === undefined ) {
+
+ // Attempt to get data from the cache
+ // with the key as-is
+ data = dataUser.get( elem, key ) ||
+
+ // Try to find dashed key if it exists (gh-2779)
+ // This is for 2.2.x only
+ dataUser.get( elem, key.replace( rmultiDash, "-$&" ).toLowerCase() );
+
+ if ( data !== undefined ) {
+ return data;
+ }
+
+ camelKey = jQuery.camelCase( key );
+
+ // Attempt to get data from the cache
+ // with the key camelized
+ data = dataUser.get( elem, camelKey );
+ if ( data !== undefined ) {
+ return data;
+ }
+
+ // Attempt to "discover" the data in
+ // HTML5 custom data-* attrs
+ data = dataAttr( elem, camelKey, undefined );
+ if ( data !== undefined ) {
+ return data;
+ }
+
+ // We tried really hard, but the data doesn't exist.
+ return;
+ }
+
+ // Set the data...
+ camelKey = jQuery.camelCase( key );
+ this.each( function() {
+
+ // First, attempt to store a copy or reference of any
+ // data that might've been store with a camelCased key.
+ var data = dataUser.get( this, camelKey );
+
+ // For HTML5 data-* attribute interop, we have to
+ // store property names with dashes in a camelCase form.
+ // This might not apply to all properties...*
+ dataUser.set( this, camelKey, value );
+
+ // *... In the case of properties that might _actually_
+ // have dashes, we need to also store a copy of that
+ // unchanged property.
+ if ( key.indexOf( "-" ) > -1 && data !== undefined ) {
+ dataUser.set( this, key, value );
+ }
+ } );
+ }, null, value, arguments.length > 1, null, true );
+ },
+
+ removeData: function( key ) {
+ return this.each( function() {
+ dataUser.remove( this, key );
+ } );
+ }
+} );
+
+
+jQuery.extend( {
+ queue: function( elem, type, data ) {
+ var queue;
+
+ if ( elem ) {
+ type = ( type || "fx" ) + "queue";
+ queue = dataPriv.get( elem, type );
+
+ // Speed up dequeue by getting out quickly if this is just a lookup
+ if ( data ) {
+ if ( !queue || jQuery.isArray( data ) ) {
+ queue = dataPriv.access( elem, type, jQuery.makeArray( data ) );
+ } else {
+ queue.push( data );
+ }
+ }
+ return queue || [];
+ }
+ },
+
+ dequeue: function( elem, type ) {
+ type = type || "fx";
+
+ var queue = jQuery.queue( elem, type ),
+ startLength = queue.length,
+ fn = queue.shift(),
+ hooks = jQuery._queueHooks( elem, type ),
+ next = function() {
+ jQuery.dequeue( elem, type );
+ };
+
+ // If the fx queue is dequeued, always remove the progress sentinel
+ if ( fn === "inprogress" ) {
+ fn = queue.shift();
+ startLength--;
+ }
+
+ if ( fn ) {
+
+ // Add a progress sentinel to prevent the fx queue from being
+ // automatically dequeued
+ if ( type === "fx" ) {
+ queue.unshift( "inprogress" );
+ }
+
+ // Clear up the last queue stop function
+ delete hooks.stop;
+ fn.call( elem, next, hooks );
+ }
+
+ if ( !startLength && hooks ) {
+ hooks.empty.fire();
+ }
+ },
+
+ // Not public - generate a queueHooks object, or return the current one
+ _queueHooks: function( elem, type ) {
+ var key = type + "queueHooks";
+ return dataPriv.get( elem, key ) || dataPriv.access( elem, key, {
+ empty: jQuery.Callbacks( "once memory" ).add( function() {
+ dataPriv.remove( elem, [ type + "queue", key ] );
+ } )
+ } );
+ }
+} );
+
+jQuery.fn.extend( {
+ queue: function( type, data ) {
+ var setter = 2;
+
+ if ( typeof type !== "string" ) {
+ data = type;
+ type = "fx";
+ setter--;
+ }
+
+ if ( arguments.length < setter ) {
+ return jQuery.queue( this[ 0 ], type );
+ }
+
+ return data === undefined ?
+ this :
+ this.each( function() {
+ var queue = jQuery.queue( this, type, data );
+
+ // Ensure a hooks for this queue
+ jQuery._queueHooks( this, type );
+
+ if ( type === "fx" && queue[ 0 ] !== "inprogress" ) {
+ jQuery.dequeue( this, type );
+ }
+ } );
+ },
+ dequeue: function( type ) {
+ return this.each( function() {
+ jQuery.dequeue( this, type );
+ } );
+ },
+ clearQueue: function( type ) {
+ return this.queue( type || "fx", [] );
+ },
+
+ // Get a promise resolved when queues of a certain type
+ // are emptied (fx is the type by default)
+ promise: function( type, obj ) {
+ var tmp,
+ count = 1,
+ defer = jQuery.Deferred(),
+ elements = this,
+ i = this.length,
+ resolve = function() {
+ if ( !( --count ) ) {
+ defer.resolveWith( elements, [ elements ] );
+ }
+ };
+
+ if ( typeof type !== "string" ) {
+ obj = type;
+ type = undefined;
+ }
+ type = type || "fx";
+
+ while ( i-- ) {
+ tmp = dataPriv.get( elements[ i ], type + "queueHooks" );
+ if ( tmp && tmp.empty ) {
+ count++;
+ tmp.empty.add( resolve );
+ }
+ }
+ resolve();
+ return defer.promise( obj );
+ }
+} );
+var pnum = ( /[+-]?(?:\d*\.|)\d+(?:[eE][+-]?\d+|)/ ).source;
+
+var rcssNum = new RegExp( "^(?:([+-])=|)(" + pnum + ")([a-z%]*)$", "i" );
+
+
+var cssExpand = [ "Top", "Right", "Bottom", "Left" ];
+
+var isHidden = function( elem, el ) {
+
+ // isHidden might be called from jQuery#filter function;
+ // in that case, element will be second argument
+ elem = el || elem;
+ return jQuery.css( elem, "display" ) === "none" ||
+ !jQuery.contains( elem.ownerDocument, elem );
+ };
+
+
+
+function adjustCSS( elem, prop, valueParts, tween ) {
+ var adjusted,
+ scale = 1,
+ maxIterations = 20,
+ currentValue = tween ?
+ function() { return tween.cur(); } :
+ function() { return jQuery.css( elem, prop, "" ); },
+ initial = currentValue(),
+ unit = valueParts && valueParts[ 3 ] || ( jQuery.cssNumber[ prop ] ? "" : "px" ),
+
+ // Starting value computation is required for potential unit mismatches
+ initialInUnit = ( jQuery.cssNumber[ prop ] || unit !== "px" && +initial ) &&
+ rcssNum.exec( jQuery.css( elem, prop ) );
+
+ if ( initialInUnit && initialInUnit[ 3 ] !== unit ) {
+
+ // Trust units reported by jQuery.css
+ unit = unit || initialInUnit[ 3 ];
+
+ // Make sure we update the tween properties later on
+ valueParts = valueParts || [];
+
+ // Iteratively approximate from a nonzero starting point
+ initialInUnit = +initial || 1;
+
+ do {
+
+ // If previous iteration zeroed out, double until we get *something*.
+ // Use string for doubling so we don't accidentally see scale as unchanged below
+ scale = scale || ".5";
+
+ // Adjust and apply
+ initialInUnit = initialInUnit / scale;
+ jQuery.style( elem, prop, initialInUnit + unit );
+
+ // Update scale, tolerating zero or NaN from tween.cur()
+ // Break the loop if scale is unchanged or perfect, or if we've just had enough.
+ } while (
+ scale !== ( scale = currentValue() / initial ) && scale !== 1 && --maxIterations
+ );
+ }
+
+ if ( valueParts ) {
+ initialInUnit = +initialInUnit || +initial || 0;
+
+ // Apply relative offset (+=/-=) if specified
+ adjusted = valueParts[ 1 ] ?
+ initialInUnit + ( valueParts[ 1 ] + 1 ) * valueParts[ 2 ] :
+ +valueParts[ 2 ];
+ if ( tween ) {
+ tween.unit = unit;
+ tween.start = initialInUnit;
+ tween.end = adjusted;
+ }
+ }
+ return adjusted;
+}
+var rcheckableType = ( /^(?:checkbox|radio)$/i );
+
+var rtagName = ( /<([\w:-]+)/ );
+
+var rscriptType = ( /^$|\/(?:java|ecma)script/i );
+
+
+
+// We have to close these tags to support XHTML (#13200)
+var wrapMap = {
+
+ // Support: IE9
+ option: [ 1, "" ],
+
+ // XHTML parsers do not magically insert elements in the
+ // same way that tag soup parsers do. So we cannot shorten
+ // this by omitting or other required elements.
+ thead: [ 1, "" ],
+ col: [ 2, "" ],
+ tr: [ 2, "" ],
+ td: [ 3, "" ],
+
+ _default: [ 0, "", "" ]
+};
+
+// Support: IE9
+wrapMap.optgroup = wrapMap.option;
+
+wrapMap.tbody = wrapMap.tfoot = wrapMap.colgroup = wrapMap.caption = wrapMap.thead;
+wrapMap.th = wrapMap.td;
+
+
+function getAll( context, tag ) {
+
+ // Support: IE9-11+
+ // Use typeof to avoid zero-argument method invocation on host objects (#15151)
+ var ret = typeof context.getElementsByTagName !== "undefined" ?
+ context.getElementsByTagName( tag || "*" ) :
+ typeof context.querySelectorAll !== "undefined" ?
+ context.querySelectorAll( tag || "*" ) :
+ [];
+
+ return tag === undefined || tag && jQuery.nodeName( context, tag ) ?
+ jQuery.merge( [ context ], ret ) :
+ ret;
+}
+
+
+// Mark scripts as having already been evaluated
+function setGlobalEval( elems, refElements ) {
+ var i = 0,
+ l = elems.length;
+
+ for ( ; i < l; i++ ) {
+ dataPriv.set(
+ elems[ i ],
+ "globalEval",
+ !refElements || dataPriv.get( refElements[ i ], "globalEval" )
+ );
+ }
+}
+
+
+var rhtml = /<|?\w+;/;
+
+function buildFragment( elems, context, scripts, selection, ignored ) {
+ var elem, tmp, tag, wrap, contains, j,
+ fragment = context.createDocumentFragment(),
+ nodes = [],
+ i = 0,
+ l = elems.length;
+
+ for ( ; i < l; i++ ) {
+ elem = elems[ i ];
+
+ if ( elem || elem === 0 ) {
+
+ // Add nodes directly
+ if ( jQuery.type( elem ) === "object" ) {
+
+ // Support: Android<4.1, PhantomJS<2
+ // push.apply(_, arraylike) throws on ancient WebKit
+ jQuery.merge( nodes, elem.nodeType ? [ elem ] : elem );
+
+ // Convert non-html into a text node
+ } else if ( !rhtml.test( elem ) ) {
+ nodes.push( context.createTextNode( elem ) );
+
+ // Convert html into DOM nodes
+ } else {
+ tmp = tmp || fragment.appendChild( context.createElement( "div" ) );
+
+ // Deserialize a standard representation
+ tag = ( rtagName.exec( elem ) || [ "", "" ] )[ 1 ].toLowerCase();
+ wrap = wrapMap[ tag ] || wrapMap._default;
+ tmp.innerHTML = wrap[ 1 ] + jQuery.htmlPrefilter( elem ) + wrap[ 2 ];
+
+ // Descend through wrappers to the right content
+ j = wrap[ 0 ];
+ while ( j-- ) {
+ tmp = tmp.lastChild;
+ }
+
+ // Support: Android<4.1, PhantomJS<2
+ // push.apply(_, arraylike) throws on ancient WebKit
+ jQuery.merge( nodes, tmp.childNodes );
+
+ // Remember the top-level container
+ tmp = fragment.firstChild;
+
+ // Ensure the created nodes are orphaned (#12392)
+ tmp.textContent = "";
+ }
+ }
+ }
+
+ // Remove wrapper from fragment
+ fragment.textContent = "";
+
+ i = 0;
+ while ( ( elem = nodes[ i++ ] ) ) {
+
+ // Skip elements already in the context collection (trac-4087)
+ if ( selection && jQuery.inArray( elem, selection ) > -1 ) {
+ if ( ignored ) {
+ ignored.push( elem );
+ }
+ continue;
+ }
+
+ contains = jQuery.contains( elem.ownerDocument, elem );
+
+ // Append to fragment
+ tmp = getAll( fragment.appendChild( elem ), "script" );
+
+ // Preserve script evaluation history
+ if ( contains ) {
+ setGlobalEval( tmp );
+ }
+
+ // Capture executables
+ if ( scripts ) {
+ j = 0;
+ while ( ( elem = tmp[ j++ ] ) ) {
+ if ( rscriptType.test( elem.type || "" ) ) {
+ scripts.push( elem );
+ }
+ }
+ }
+ }
+
+ return fragment;
+}
+
+
+( function() {
+ var fragment = document.createDocumentFragment(),
+ div = fragment.appendChild( document.createElement( "div" ) ),
+ input = document.createElement( "input" );
+
+ // Support: Android 4.0-4.3, Safari<=5.1
+ // Check state lost if the name is set (#11217)
+ // Support: Windows Web Apps (WWA)
+ // `name` and `type` must use .setAttribute for WWA (#14901)
+ input.setAttribute( "type", "radio" );
+ input.setAttribute( "checked", "checked" );
+ input.setAttribute( "name", "t" );
+
+ div.appendChild( input );
+
+ // Support: Safari<=5.1, Android<4.2
+ // Older WebKit doesn't clone checked state correctly in fragments
+ support.checkClone = div.cloneNode( true ).cloneNode( true ).lastChild.checked;
+
+ // Support: IE<=11+
+ // Make sure textarea (and checkbox) defaultValue is properly cloned
+ div.innerHTML = "";
+ support.noCloneChecked = !!div.cloneNode( true ).lastChild.defaultValue;
+} )();
+
+
+var
+ rkeyEvent = /^key/,
+ rmouseEvent = /^(?:mouse|pointer|contextmenu|drag|drop)|click/,
+ rtypenamespace = /^([^.]*)(?:\.(.+)|)/;
+
+function returnTrue() {
+ return true;
+}
+
+function returnFalse() {
+ return false;
+}
+
+// Support: IE9
+// See #13393 for more info
+function safeActiveElement() {
+ try {
+ return document.activeElement;
+ } catch ( err ) { }
+}
+
+function on( elem, types, selector, data, fn, one ) {
+ var origFn, type;
+
+ // Types can be a map of types/handlers
+ if ( typeof types === "object" ) {
+
+ // ( types-Object, selector, data )
+ if ( typeof selector !== "string" ) {
+
+ // ( types-Object, data )
+ data = data || selector;
+ selector = undefined;
+ }
+ for ( type in types ) {
+ on( elem, type, selector, data, types[ type ], one );
+ }
+ return elem;
+ }
+
+ if ( data == null && fn == null ) {
+
+ // ( types, fn )
+ fn = selector;
+ data = selector = undefined;
+ } else if ( fn == null ) {
+ if ( typeof selector === "string" ) {
+
+ // ( types, selector, fn )
+ fn = data;
+ data = undefined;
+ } else {
+
+ // ( types, data, fn )
+ fn = data;
+ data = selector;
+ selector = undefined;
+ }
+ }
+ if ( fn === false ) {
+ fn = returnFalse;
+ } else if ( !fn ) {
+ return elem;
+ }
+
+ if ( one === 1 ) {
+ origFn = fn;
+ fn = function( event ) {
+
+ // Can use an empty set, since event contains the info
+ jQuery().off( event );
+ return origFn.apply( this, arguments );
+ };
+
+ // Use same guid so caller can remove using origFn
+ fn.guid = origFn.guid || ( origFn.guid = jQuery.guid++ );
+ }
+ return elem.each( function() {
+ jQuery.event.add( this, types, fn, data, selector );
+ } );
+}
+
+/*
+ * Helper functions for managing events -- not part of the public interface.
+ * Props to Dean Edwards' addEvent library for many of the ideas.
+ */
+jQuery.event = {
+
+ global: {},
+
+ add: function( elem, types, handler, data, selector ) {
+
+ var handleObjIn, eventHandle, tmp,
+ events, t, handleObj,
+ special, handlers, type, namespaces, origType,
+ elemData = dataPriv.get( elem );
+
+ // Don't attach events to noData or text/comment nodes (but allow plain objects)
+ if ( !elemData ) {
+ return;
+ }
+
+ // Caller can pass in an object of custom data in lieu of the handler
+ if ( handler.handler ) {
+ handleObjIn = handler;
+ handler = handleObjIn.handler;
+ selector = handleObjIn.selector;
+ }
+
+ // Make sure that the handler has a unique ID, used to find/remove it later
+ if ( !handler.guid ) {
+ handler.guid = jQuery.guid++;
+ }
+
+ // Init the element's event structure and main handler, if this is the first
+ if ( !( events = elemData.events ) ) {
+ events = elemData.events = {};
+ }
+ if ( !( eventHandle = elemData.handle ) ) {
+ eventHandle = elemData.handle = function( e ) {
+
+ // Discard the second event of a jQuery.event.trigger() and
+ // when an event is called after a page has unloaded
+ return typeof jQuery !== "undefined" && jQuery.event.triggered !== e.type ?
+ jQuery.event.dispatch.apply( elem, arguments ) : undefined;
+ };
+ }
+
+ // Handle multiple events separated by a space
+ types = ( types || "" ).match( rnotwhite ) || [ "" ];
+ t = types.length;
+ while ( t-- ) {
+ tmp = rtypenamespace.exec( types[ t ] ) || [];
+ type = origType = tmp[ 1 ];
+ namespaces = ( tmp[ 2 ] || "" ).split( "." ).sort();
+
+ // There *must* be a type, no attaching namespace-only handlers
+ if ( !type ) {
+ continue;
+ }
+
+ // If event changes its type, use the special event handlers for the changed type
+ special = jQuery.event.special[ type ] || {};
+
+ // If selector defined, determine special event api type, otherwise given type
+ type = ( selector ? special.delegateType : special.bindType ) || type;
+
+ // Update special based on newly reset type
+ special = jQuery.event.special[ type ] || {};
+
+ // handleObj is passed to all event handlers
+ handleObj = jQuery.extend( {
+ type: type,
+ origType: origType,
+ data: data,
+ handler: handler,
+ guid: handler.guid,
+ selector: selector,
+ needsContext: selector && jQuery.expr.match.needsContext.test( selector ),
+ namespace: namespaces.join( "." )
+ }, handleObjIn );
+
+ // Init the event handler queue if we're the first
+ if ( !( handlers = events[ type ] ) ) {
+ handlers = events[ type ] = [];
+ handlers.delegateCount = 0;
+
+ // Only use addEventListener if the special events handler returns false
+ if ( !special.setup ||
+ special.setup.call( elem, data, namespaces, eventHandle ) === false ) {
+
+ if ( elem.addEventListener ) {
+ elem.addEventListener( type, eventHandle );
+ }
+ }
+ }
+
+ if ( special.add ) {
+ special.add.call( elem, handleObj );
+
+ if ( !handleObj.handler.guid ) {
+ handleObj.handler.guid = handler.guid;
+ }
+ }
+
+ // Add to the element's handler list, delegates in front
+ if ( selector ) {
+ handlers.splice( handlers.delegateCount++, 0, handleObj );
+ } else {
+ handlers.push( handleObj );
+ }
+
+ // Keep track of which events have ever been used, for event optimization
+ jQuery.event.global[ type ] = true;
+ }
+
+ },
+
+ // Detach an event or set of events from an element
+ remove: function( elem, types, handler, selector, mappedTypes ) {
+
+ var j, origCount, tmp,
+ events, t, handleObj,
+ special, handlers, type, namespaces, origType,
+ elemData = dataPriv.hasData( elem ) && dataPriv.get( elem );
+
+ if ( !elemData || !( events = elemData.events ) ) {
+ return;
+ }
+
+ // Once for each type.namespace in types; type may be omitted
+ types = ( types || "" ).match( rnotwhite ) || [ "" ];
+ t = types.length;
+ while ( t-- ) {
+ tmp = rtypenamespace.exec( types[ t ] ) || [];
+ type = origType = tmp[ 1 ];
+ namespaces = ( tmp[ 2 ] || "" ).split( "." ).sort();
+
+ // Unbind all events (on this namespace, if provided) for the element
+ if ( !type ) {
+ for ( type in events ) {
+ jQuery.event.remove( elem, type + types[ t ], handler, selector, true );
+ }
+ continue;
+ }
+
+ special = jQuery.event.special[ type ] || {};
+ type = ( selector ? special.delegateType : special.bindType ) || type;
+ handlers = events[ type ] || [];
+ tmp = tmp[ 2 ] &&
+ new RegExp( "(^|\\.)" + namespaces.join( "\\.(?:.*\\.|)" ) + "(\\.|$)" );
+
+ // Remove matching events
+ origCount = j = handlers.length;
+ while ( j-- ) {
+ handleObj = handlers[ j ];
+
+ if ( ( mappedTypes || origType === handleObj.origType ) &&
+ ( !handler || handler.guid === handleObj.guid ) &&
+ ( !tmp || tmp.test( handleObj.namespace ) ) &&
+ ( !selector || selector === handleObj.selector ||
+ selector === "**" && handleObj.selector ) ) {
+ handlers.splice( j, 1 );
+
+ if ( handleObj.selector ) {
+ handlers.delegateCount--;
+ }
+ if ( special.remove ) {
+ special.remove.call( elem, handleObj );
+ }
+ }
+ }
+
+ // Remove generic event handler if we removed something and no more handlers exist
+ // (avoids potential for endless recursion during removal of special event handlers)
+ if ( origCount && !handlers.length ) {
+ if ( !special.teardown ||
+ special.teardown.call( elem, namespaces, elemData.handle ) === false ) {
+
+ jQuery.removeEvent( elem, type, elemData.handle );
+ }
+
+ delete events[ type ];
+ }
+ }
+
+ // Remove data and the expando if it's no longer used
+ if ( jQuery.isEmptyObject( events ) ) {
+ dataPriv.remove( elem, "handle events" );
+ }
+ },
+
+ dispatch: function( event ) {
+
+ // Make a writable jQuery.Event from the native event object
+ event = jQuery.event.fix( event );
+
+ var i, j, ret, matched, handleObj,
+ handlerQueue = [],
+ args = slice.call( arguments ),
+ handlers = ( dataPriv.get( this, "events" ) || {} )[ event.type ] || [],
+ special = jQuery.event.special[ event.type ] || {};
+
+ // Use the fix-ed jQuery.Event rather than the (read-only) native event
+ args[ 0 ] = event;
+ event.delegateTarget = this;
+
+ // Call the preDispatch hook for the mapped type, and let it bail if desired
+ if ( special.preDispatch && special.preDispatch.call( this, event ) === false ) {
+ return;
+ }
+
+ // Determine handlers
+ handlerQueue = jQuery.event.handlers.call( this, event, handlers );
+
+ // Run delegates first; they may want to stop propagation beneath us
+ i = 0;
+ while ( ( matched = handlerQueue[ i++ ] ) && !event.isPropagationStopped() ) {
+ event.currentTarget = matched.elem;
+
+ j = 0;
+ while ( ( handleObj = matched.handlers[ j++ ] ) &&
+ !event.isImmediatePropagationStopped() ) {
+
+ // Triggered event must either 1) have no namespace, or 2) have namespace(s)
+ // a subset or equal to those in the bound event (both can have no namespace).
+ if ( !event.rnamespace || event.rnamespace.test( handleObj.namespace ) ) {
+
+ event.handleObj = handleObj;
+ event.data = handleObj.data;
+
+ ret = ( ( jQuery.event.special[ handleObj.origType ] || {} ).handle ||
+ handleObj.handler ).apply( matched.elem, args );
+
+ if ( ret !== undefined ) {
+ if ( ( event.result = ret ) === false ) {
+ event.preventDefault();
+ event.stopPropagation();
+ }
+ }
+ }
+ }
+ }
+
+ // Call the postDispatch hook for the mapped type
+ if ( special.postDispatch ) {
+ special.postDispatch.call( this, event );
+ }
+
+ return event.result;
+ },
+
+ handlers: function( event, handlers ) {
+ var i, matches, sel, handleObj,
+ handlerQueue = [],
+ delegateCount = handlers.delegateCount,
+ cur = event.target;
+
+ // Support (at least): Chrome, IE9
+ // Find delegate handlers
+ // Black-hole SVG