You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@ambari.apache.org by rz...@apache.org on 2015/07/21 02:11:04 UTC
ambari git commit: AMBARI-12141. Kerberos configs aren't restored
when moving back from Review to the Configure Identities step (rzang)
Repository: ambari
Updated Branches:
refs/heads/trunk 305911ef8 -> b951789d6
AMBARI-12141. Kerberos configs aren't restored when moving back from Review to the Configure Identities step (rzang)
Project: http://git-wip-us.apache.org/repos/asf/ambari/repo
Commit: http://git-wip-us.apache.org/repos/asf/ambari/commit/b951789d
Tree: http://git-wip-us.apache.org/repos/asf/ambari/tree/b951789d
Diff: http://git-wip-us.apache.org/repos/asf/ambari/diff/b951789d
Branch: refs/heads/trunk
Commit: b951789d64e0aa617ffe7d7bbaa4b89292250375
Parents: 305911e
Author: Richard Zang <rz...@apache.org>
Authored: Mon Jul 20 17:08:47 2015 -0700
Committer: Richard Zang <rz...@apache.org>
Committed: Mon Jul 20 17:10:11 2015 -0700
----------------------------------------------------------------------
.../main/admin/kerberos/step2_controller.js | 2 +-
.../main/admin/kerberos/step4_controller.js | 14 +-
ambari-web/app/controllers/wizard.js | 29 ++
ambari-web/app/routes/add_kerberos_routes.js | 2 +
ambari-web/app/routes/add_service_routes.js | 2 +
ambari-web/app/utils/config.js | 17 +
.../admin/kerberos/step4_controller_test.js | 6 +
ambari-web/vendor/scripts/lz-string.js | 492 +++++++++++++++++++
8 files changed, 561 insertions(+), 3 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/ambari/blob/b951789d/ambari-web/app/controllers/main/admin/kerberos/step2_controller.js
----------------------------------------------------------------------
diff --git a/ambari-web/app/controllers/main/admin/kerberos/step2_controller.js b/ambari-web/app/controllers/main/admin/kerberos/step2_controller.js
index c843d9a..0691891 100644
--- a/ambari-web/app/controllers/main/admin/kerberos/step2_controller.js
+++ b/ambari-web/app/controllers/main/admin/kerberos/step2_controller.js
@@ -77,7 +77,7 @@ App.KerberosWizardStep2Controller = App.WizardStep7Controller.extend({
* @method loadStep
*/
loadStep: function () {
- console.log("TRACE: Loading step7: Configure Services");
+ console.log("TRACE: Loading step2: Configure Kerberos");
if (!App.StackService.find().someProperty('serviceName', 'KERBEROS') || !this.get('isConfigsLoaded')) {
return;
}
http://git-wip-us.apache.org/repos/asf/ambari/blob/b951789d/ambari-web/app/controllers/main/admin/kerberos/step4_controller.js
----------------------------------------------------------------------
diff --git a/ambari-web/app/controllers/main/admin/kerberos/step4_controller.js b/ambari-web/app/controllers/main/admin/kerberos/step4_controller.js
index 08f4e10..500f2c7 100644
--- a/ambari-web/app/controllers/main/admin/kerberos/step4_controller.js
+++ b/ambari-web/app/controllers/main/admin/kerberos/step4_controller.js
@@ -21,6 +21,9 @@ require('controllers/wizard/step7_controller');
App.KerberosWizardStep4Controller = App.WizardStep7Controller.extend(App.AddSecurityConfigs, App.ToggleIsRequiredMixin, {
name: 'kerberosWizardStep4Controller',
+ isWithinAddService: function () {
+ return this.get('wizardController.name') == 'addServiceController';
+ }.property('wizardController.name'),
adminPropertyNames: [{name: 'admin_principal', displayName: 'Admin principal'}, {name: 'admin_password', displayName: 'Admin password'}],
@@ -166,13 +169,20 @@ App.KerberosWizardStep4Controller = App.WizardStep7Controller.extend(App.AddSecu
* @returns {App.ServiceConfigProperty[]}
*/
prepareConfigProperties: function(configs) {
+ console.log("call prepare");
var self = this;
var storedServiceConfigs = this.get('wizardController').getDBProperty('serviceConfigProperties');
var installedServiceNames = ['Cluster'].concat(App.Service.find().mapProperty('serviceName'));
var adminProps = [];
var configProperties = configs.slice(0);
var siteProperties = App.config.get('preDefinedSiteProperties');
- if (this.get('wizardController.name') == 'addServiceController') {
+ // override stored values
+ App.config.mergeStoredValue(configProperties, storedServiceConfigs);
+ console.log(this.get('wizardController'));
+ App.config.mergeStoredValue(configProperties, this.get('wizardController').loadCachedStepConfigValues(this));
+
+ // show admin properties in add service wizard
+ if (this.get('isWithinAddService')) {
installedServiceNames = installedServiceNames.concat(this.get('selectedServiceNames'));
this.get('adminPropertyNames').forEach(function(item) {
var property = storedServiceConfigs.filterProperty('filename', 'krb5-conf.xml').findProperty('name', item.name);
@@ -188,8 +198,8 @@ App.KerberosWizardStep4Controller = App.WizardStep7Controller.extend(App.AddSecu
adminProps.push(_prop);
}
});
- configProperties = adminProps.concat(configProperties);
}
+ configProperties = adminProps.concat(configProperties);
configProperties = configProperties.filter(function(item) {
return installedServiceNames.contains(item.get('serviceName'));
});
http://git-wip-us.apache.org/repos/asf/ambari/blob/b951789d/ambari-web/app/controllers/wizard.js
----------------------------------------------------------------------
diff --git a/ambari-web/app/controllers/wizard.js b/ambari-web/app/controllers/wizard.js
index b1e7073..102d64c 100644
--- a/ambari-web/app/controllers/wizard.js
+++ b/ambari-web/app/controllers/wizard.js
@@ -1280,6 +1280,35 @@ App.WizardController = Em.Controller.extend(App.LocalStorage, App.ThemesMappingM
return dfd.promise();
},
+
+ /**
+ * Cache all step config to local storage in name value pairs
+ * @param stepController
+ */
+ cacheStepConfigValues: function(stepController) {
+ var stepConfigs = [];
+ stepController.get("stepConfigs").forEach(function (category) {
+ var configs = category.configs.map(function(config) {
+ return {
+ name: config.name,
+ value: config.value
+ };
+ });
+ stepConfigs = stepConfigs.concat(configs);
+ });
+ if (stepConfigs.length > 0 ) {
+ this.setDBProperty(stepController.name + "-sc", stepConfigs);
+ }
+ },
+
+ loadCachedStepConfigValues: function(stepController) {
+ return this.getDBProperty(stepController.name + "-sc");
+ },
+
+ clearCachedStepConfigValues: function(stepController) {
+ this.setDBProperty(stepController.name + "-sc", null);
+ },
+
saveTasksStatuses: function (tasksStatuses) {
this.set('content.tasksStatuses', tasksStatuses);
this.setDBProperty('tasksStatuses', tasksStatuses);
http://git-wip-us.apache.org/repos/asf/ambari/blob/b951789d/ambari-web/app/routes/add_kerberos_routes.js
----------------------------------------------------------------------
diff --git a/ambari-web/app/routes/add_kerberos_routes.js b/ambari-web/app/routes/add_kerberos_routes.js
index e3a40f8..716d738 100644
--- a/ambari-web/app/routes/add_kerberos_routes.js
+++ b/ambari-web/app/routes/add_kerberos_routes.js
@@ -210,6 +210,7 @@ module.exports = App.WizardRoute.extend({
next: function (router) {
var kerberosWizardController = router.get('kerberosWizardController');
kerberosWizardController.setDBProperty('kerberosDescriptorConfigs', null);
+ kerberosWizardController.clearCachedStepConfigValues(router.get('kerberosWizardStep4Controller'));
router.transitionTo('step4');
}
}),
@@ -244,6 +245,7 @@ module.exports = App.WizardRoute.extend({
var kerberosWizardController = router.get('kerberosWizardController');
var step5Controller = router.get('kerberosWizardStep5Controller');
var kerberosDescriptor = kerberosWizardController.get('kerberosDescriptorConfigs');
+ kerberosWizardController.cacheStepConfigValues(router.get('kerberosWizardStep4Controller'));
step5Controller.postKerberosDescriptor(kerberosDescriptor).always(function (data, result, request) {
if (result === 'error' && data.status === 409) {
step5Controller.putKerberosDescriptor(kerberosDescriptor);
http://git-wip-us.apache.org/repos/asf/ambari/blob/b951789d/ambari-web/app/routes/add_service_routes.js
----------------------------------------------------------------------
diff --git a/ambari-web/app/routes/add_service_routes.js b/ambari-web/app/routes/add_service_routes.js
index 2df6c99..c646002 100644
--- a/ambari-web/app/routes/add_service_routes.js
+++ b/ambari-web/app/routes/add_service_routes.js
@@ -226,6 +226,7 @@ module.exports = App.WizardRoute.extend({
addServiceController.saveServiceConfigProperties(wizardStep7Controller);
addServiceController.saveServiceConfigGroups(wizardStep7Controller, true);
if (router.get('mainAdminKerberosController.securityEnabled')) {
+ addServiceController.clearCachedStepConfigValues(router.get('kerberosWizardStep4Controller'));
router.transitionTo('step5');
return;
}
@@ -272,6 +273,7 @@ module.exports = App.WizardRoute.extend({
} else {
router.get('kerberosWizardStep2Controller').createKerberosAdminSession(router.get('kerberosWizardStep4Controller.stepConfigs')[0].get('configs'));
}
+ router.get('addServiceController').cacheStepConfigValues(router.get('kerberosWizardStep4Controller'));
}
router.transitionTo('step6');
}
http://git-wip-us.apache.org/repos/asf/ambari/blob/b951789d/ambari-web/app/utils/config.js
----------------------------------------------------------------------
diff --git a/ambari-web/app/utils/config.js b/ambari-web/app/utils/config.js
index b209526..c229d1d 100644
--- a/ambari-web/app/utils/config.js
+++ b/ambari-web/app/utils/config.js
@@ -1759,5 +1759,22 @@ App.config = Em.Object.create({
newOverride.validate();
return newOverride;
+ },
+
+
+ /**
+ * Merge values in "stored" to "base" if name matches, it's a value only merge.
+ * @param base {Array} Em.Object
+ * @param stored {Array} Object
+ */
+ mergeStoredValue: function(base, stored) {
+ if (stored) {
+ base.forEach(function (p) {
+ var sp = stored.findProperty("name", p.name);
+ if (sp) {
+ p.set("value", sp.value);
+ }
+ });
+ }
}
});
http://git-wip-us.apache.org/repos/asf/ambari/blob/b951789d/ambari-web/test/controllers/main/admin/kerberos/step4_controller_test.js
----------------------------------------------------------------------
diff --git a/ambari-web/test/controllers/main/admin/kerberos/step4_controller_test.js b/ambari-web/test/controllers/main/admin/kerberos/step4_controller_test.js
index 4a95297..e52d8a5 100644
--- a/ambari-web/test/controllers/main/admin/kerberos/step4_controller_test.js
+++ b/ambari-web/test/controllers/main/admin/kerberos/step4_controller_test.js
@@ -58,6 +58,9 @@ describe('App.KerberosWizardStep4Controller', function() {
return Em.A([
Em.Object.create({ name: 'realm', value: 'realm_value' })
]);
+ },
+ loadCachedStepConfigValues: function() {
+ return null;
}
}
});
@@ -185,6 +188,9 @@ describe('App.KerberosWizardStep4Controller', function() {
Em.Object.create({ name: 'admin_principal', value: 'some_val1', recommendedValue: 'some_val1', filename: 'krb5-conf.xml' }),
Em.Object.create({ name: 'admin_password', value: 'some_password', recommendedValue: 'some_password', filename: 'krb5-conf.xml' })
]);
+ },
+ loadCachedStepConfigValues : function() {
+ return null;
}
})
});
http://git-wip-us.apache.org/repos/asf/ambari/blob/b951789d/ambari-web/vendor/scripts/lz-string.js
----------------------------------------------------------------------
diff --git a/ambari-web/vendor/scripts/lz-string.js b/ambari-web/vendor/scripts/lz-string.js
new file mode 100644
index 0000000..7a8753d
--- /dev/null
+++ b/ambari-web/vendor/scripts/lz-string.js
@@ -0,0 +1,492 @@
+var LZString = (function() {
+
+// private property
+ var f = String.fromCharCode;
+ var keyStrBase64 = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=";
+ var keyStrUriSafe = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+-$";
+ var baseReverseDic = {};
+
+ function getBaseValue(alphabet, character) {
+ if (!baseReverseDic[alphabet]) {
+ baseReverseDic[alphabet] = {};
+ for (var i=0 ; i<alphabet.length ; i++) {
+ baseReverseDic[alphabet][alphabet.charAt(i)] = i;
+ }
+ }
+ return baseReverseDic[alphabet][character];
+ }
+
+ var LZString = {
+ compressToBase64 : function (input) {
+ if (input == null) return "";
+ var res = LZString._compress(input, 6, function(a){return keyStrBase64.charAt(a);});
+ switch (res.length % 4) { // To produce valid Base64
+ default: // When could this happen ?
+ case 0 : return res;
+ case 1 : return res+"===";
+ case 2 : return res+"==";
+ case 3 : return res+"=";
+ }
+ },
+
+ decompressFromBase64 : function (input) {
+ if (input == null) return "";
+ if (input == "") return null;
+ return LZString._decompress(input.length, 32, function(index) { return getBaseValue(keyStrBase64, input.charAt(index)); });
+ },
+
+ compressToUTF16 : function (input) {
+ if (input == null) return "";
+ return LZString._compress(input, 15, function(a){return f(a+32);}) + " ";
+ },
+
+ decompressFromUTF16: function (compressed) {
+ if (compressed == null) return "";
+ if (compressed == "") return null;
+ return LZString._decompress(compressed.length, 16384, function(index) { return compressed.charCodeAt(index) - 32; });
+ },
+
+ //compress into uint8array (UCS-2 big endian format)
+ compressToUint8Array: function (uncompressed) {
+ var compressed = LZString.compress(uncompressed);
+ var buf=new Uint8Array(compressed.length*2); // 2 bytes per character
+
+ for (var i=0, TotalLen=compressed.length; i<TotalLen; i++) {
+ var current_value = compressed.charCodeAt(i);
+ buf[i*2] = current_value >>> 8;
+ buf[i*2+1] = current_value % 256;
+ }
+ return buf;
+ },
+
+ //decompress from uint8array (UCS-2 big endian format)
+ decompressFromUint8Array:function (compressed) {
+ if (compressed===null || compressed===undefined){
+ return LZString.decompress(compressed);
+ } else {
+ var buf=new Array(compressed.length/2); // 2 bytes per character
+ for (var i=0, TotalLen=buf.length; i<TotalLen; i++) {
+ buf[i]=compressed[i*2]*256+compressed[i*2+1];
+ }
+
+ var result = [];
+ buf.forEach(function (c) {
+ result.push(f(c));
+ });
+ return LZString.decompress(result.join(''));
+
+ }
+
+ },
+
+
+ //compress into a string that is already URI encoded
+ compressToEncodedURIComponent: function (input) {
+ if (input == null) return "";
+ return LZString._compress(input, 6, function(a){return keyStrUriSafe.charAt(a);});
+ },
+
+ //decompress from an output of compressToEncodedURIComponent
+ decompressFromEncodedURIComponent:function (input) {
+ if (input == null) return "";
+ if (input == "") return null;
+ input = input.replace(/ /g, "+");
+ return LZString._decompress(input.length, 32, function(index) { return getBaseValue(keyStrUriSafe, input.charAt(index)); });
+ },
+
+ compress: function (uncompressed) {
+ return LZString._compress(uncompressed, 16, function(a){return f(a);});
+ },
+ _compress: function (uncompressed, bitsPerChar, getCharFromInt) {
+ if (uncompressed == null) return "";
+ var i, value,
+ context_dictionary= {},
+ context_dictionaryToCreate= {},
+ context_c="",
+ context_wc="",
+ context_w="",
+ context_enlargeIn= 2, // Compensate for the first entry which should not count
+ context_dictSize= 3,
+ context_numBits= 2,
+ context_data=[],
+ context_data_val=0,
+ context_data_position=0,
+ ii;
+
+ for (ii = 0; ii < uncompressed.length; ii += 1) {
+ context_c = uncompressed.charAt(ii);
+ if (!Object.prototype.hasOwnProperty.call(context_dictionary,context_c)) {
+ context_dictionary[context_c] = context_dictSize++;
+ context_dictionaryToCreate[context_c] = true;
+ }
+
+ context_wc = context_w + context_c;
+ if (Object.prototype.hasOwnProperty.call(context_dictionary,context_wc)) {
+ context_w = context_wc;
+ } else {
+ if (Object.prototype.hasOwnProperty.call(context_dictionaryToCreate,context_w)) {
+ if (context_w.charCodeAt(0)<256) {
+ for (i=0 ; i<context_numBits ; i++) {
+ context_data_val = (context_data_val << 1);
+ if (context_data_position == bitsPerChar-1) {
+ context_data_position = 0;
+ context_data.push(getCharFromInt(context_data_val));
+ context_data_val = 0;
+ } else {
+ context_data_position++;
+ }
+ }
+ value = context_w.charCodeAt(0);
+ for (i=0 ; i<8 ; i++) {
+ context_data_val = (context_data_val << 1) | (value&1);
+ if (context_data_position == bitsPerChar-1) {
+ context_data_position = 0;
+ context_data.push(getCharFromInt(context_data_val));
+ context_data_val = 0;
+ } else {
+ context_data_position++;
+ }
+ value = value >> 1;
+ }
+ } else {
+ value = 1;
+ for (i=0 ; i<context_numBits ; i++) {
+ context_data_val = (context_data_val << 1) | value;
+ if (context_data_position ==bitsPerChar-1) {
+ context_data_position = 0;
+ context_data.push(getCharFromInt(context_data_val));
+ context_data_val = 0;
+ } else {
+ context_data_position++;
+ }
+ value = 0;
+ }
+ value = context_w.charCodeAt(0);
+ for (i=0 ; i<16 ; i++) {
+ context_data_val = (context_data_val << 1) | (value&1);
+ if (context_data_position == bitsPerChar-1) {
+ context_data_position = 0;
+ context_data.push(getCharFromInt(context_data_val));
+ context_data_val = 0;
+ } else {
+ context_data_position++;
+ }
+ value = value >> 1;
+ }
+ }
+ context_enlargeIn--;
+ if (context_enlargeIn == 0) {
+ context_enlargeIn = Math.pow(2, context_numBits);
+ context_numBits++;
+ }
+ delete context_dictionaryToCreate[context_w];
+ } else {
+ value = context_dictionary[context_w];
+ for (i=0 ; i<context_numBits ; i++) {
+ context_data_val = (context_data_val << 1) | (value&1);
+ if (context_data_position == bitsPerChar-1) {
+ context_data_position = 0;
+ context_data.push(getCharFromInt(context_data_val));
+ context_data_val = 0;
+ } else {
+ context_data_position++;
+ }
+ value = value >> 1;
+ }
+
+
+ }
+ context_enlargeIn--;
+ if (context_enlargeIn == 0) {
+ context_enlargeIn = Math.pow(2, context_numBits);
+ context_numBits++;
+ }
+ // Add wc to the dictionary.
+ context_dictionary[context_wc] = context_dictSize++;
+ context_w = String(context_c);
+ }
+ }
+
+ // Output the code for w.
+ if (context_w !== "") {
+ if (Object.prototype.hasOwnProperty.call(context_dictionaryToCreate,context_w)) {
+ if (context_w.charCodeAt(0)<256) {
+ for (i=0 ; i<context_numBits ; i++) {
+ context_data_val = (context_data_val << 1);
+ if (context_data_position == bitsPerChar-1) {
+ context_data_position = 0;
+ context_data.push(getCharFromInt(context_data_val));
+ context_data_val = 0;
+ } else {
+ context_data_position++;
+ }
+ }
+ value = context_w.charCodeAt(0);
+ for (i=0 ; i<8 ; i++) {
+ context_data_val = (context_data_val << 1) | (value&1);
+ if (context_data_position == bitsPerChar-1) {
+ context_data_position = 0;
+ context_data.push(getCharFromInt(context_data_val));
+ context_data_val = 0;
+ } else {
+ context_data_position++;
+ }
+ value = value >> 1;
+ }
+ } else {
+ value = 1;
+ for (i=0 ; i<context_numBits ; i++) {
+ context_data_val = (context_data_val << 1) | value;
+ if (context_data_position == bitsPerChar-1) {
+ context_data_position = 0;
+ context_data.push(getCharFromInt(context_data_val));
+ context_data_val = 0;
+ } else {
+ context_data_position++;
+ }
+ value = 0;
+ }
+ value = context_w.charCodeAt(0);
+ for (i=0 ; i<16 ; i++) {
+ context_data_val = (context_data_val << 1) | (value&1);
+ if (context_data_position == bitsPerChar-1) {
+ context_data_position = 0;
+ context_data.push(getCharFromInt(context_data_val));
+ context_data_val = 0;
+ } else {
+ context_data_position++;
+ }
+ value = value >> 1;
+ }
+ }
+ context_enlargeIn--;
+ if (context_enlargeIn == 0) {
+ context_enlargeIn = Math.pow(2, context_numBits);
+ context_numBits++;
+ }
+ delete context_dictionaryToCreate[context_w];
+ } else {
+ value = context_dictionary[context_w];
+ for (i=0 ; i<context_numBits ; i++) {
+ context_data_val = (context_data_val << 1) | (value&1);
+ if (context_data_position == bitsPerChar-1) {
+ context_data_position = 0;
+ context_data.push(getCharFromInt(context_data_val));
+ context_data_val = 0;
+ } else {
+ context_data_position++;
+ }
+ value = value >> 1;
+ }
+
+
+ }
+ context_enlargeIn--;
+ if (context_enlargeIn == 0) {
+ context_enlargeIn = Math.pow(2, context_numBits);
+ context_numBits++;
+ }
+ }
+
+ // Mark the end of the stream
+ value = 2;
+ for (i=0 ; i<context_numBits ; i++) {
+ context_data_val = (context_data_val << 1) | (value&1);
+ if (context_data_position == bitsPerChar-1) {
+ context_data_position = 0;
+ context_data.push(getCharFromInt(context_data_val));
+ context_data_val = 0;
+ } else {
+ context_data_position++;
+ }
+ value = value >> 1;
+ }
+
+ // Flush the last char
+ while (true) {
+ context_data_val = (context_data_val << 1);
+ if (context_data_position == bitsPerChar-1) {
+ context_data.push(getCharFromInt(context_data_val));
+ break;
+ }
+ else context_data_position++;
+ }
+ return context_data.join('');
+ },
+
+ decompress: function (compressed) {
+ if (compressed == null) return "";
+ if (compressed == "") return null;
+ return LZString._decompress(compressed.length, 32768, function(index) { return compressed.charCodeAt(index); });
+ },
+
+ _decompress: function (length, resetValue, getNextValue) {
+ var dictionary = [],
+ next,
+ enlargeIn = 4,
+ dictSize = 4,
+ numBits = 3,
+ entry = "",
+ result = [],
+ i,
+ w,
+ bits, resb, maxpower, power,
+ c,
+ data = {val:getNextValue(0), position:resetValue, index:1};
+
+ for (i = 0; i < 3; i += 1) {
+ dictionary[i] = i;
+ }
+
+ bits = 0;
+ maxpower = Math.pow(2,2);
+ power=1;
+ while (power!=maxpower) {
+ resb = data.val & data.position;
+ data.position >>= 1;
+ if (data.position == 0) {
+ data.position = resetValue;
+ data.val = getNextValue(data.index++);
+ }
+ bits |= (resb>0 ? 1 : 0) * power;
+ power <<= 1;
+ }
+
+ switch (next = bits) {
+ case 0:
+ bits = 0;
+ maxpower = Math.pow(2,8);
+ power=1;
+ while (power!=maxpower) {
+ resb = data.val & data.position;
+ data.position >>= 1;
+ if (data.position == 0) {
+ data.position = resetValue;
+ data.val = getNextValue(data.index++);
+ }
+ bits |= (resb>0 ? 1 : 0) * power;
+ power <<= 1;
+ }
+ c = f(bits);
+ break;
+ case 1:
+ bits = 0;
+ maxpower = Math.pow(2,16);
+ power=1;
+ while (power!=maxpower) {
+ resb = data.val & data.position;
+ data.position >>= 1;
+ if (data.position == 0) {
+ data.position = resetValue;
+ data.val = getNextValue(data.index++);
+ }
+ bits |= (resb>0 ? 1 : 0) * power;
+ power <<= 1;
+ }
+ c = f(bits);
+ break;
+ case 2:
+ return "";
+ }
+ dictionary[3] = c;
+ w = c;
+ result.push(c);
+ while (true) {
+ if (data.index > length) {
+ return "";
+ }
+
+ bits = 0;
+ maxpower = Math.pow(2,numBits);
+ power=1;
+ while (power!=maxpower) {
+ resb = data.val & data.position;
+ data.position >>= 1;
+ if (data.position == 0) {
+ data.position = resetValue;
+ data.val = getNextValue(data.index++);
+ }
+ bits |= (resb>0 ? 1 : 0) * power;
+ power <<= 1;
+ }
+
+ switch (c = bits) {
+ case 0:
+ bits = 0;
+ maxpower = Math.pow(2,8);
+ power=1;
+ while (power!=maxpower) {
+ resb = data.val & data.position;
+ data.position >>= 1;
+ if (data.position == 0) {
+ data.position = resetValue;
+ data.val = getNextValue(data.index++);
+ }
+ bits |= (resb>0 ? 1 : 0) * power;
+ power <<= 1;
+ }
+
+ dictionary[dictSize++] = f(bits);
+ c = dictSize-1;
+ enlargeIn--;
+ break;
+ case 1:
+ bits = 0;
+ maxpower = Math.pow(2,16);
+ power=1;
+ while (power!=maxpower) {
+ resb = data.val & data.position;
+ data.position >>= 1;
+ if (data.position == 0) {
+ data.position = resetValue;
+ data.val = getNextValue(data.index++);
+ }
+ bits |= (resb>0 ? 1 : 0) * power;
+ power <<= 1;
+ }
+ dictionary[dictSize++] = f(bits);
+ c = dictSize-1;
+ enlargeIn--;
+ break;
+ case 2:
+ return result.join('');
+ }
+
+ if (enlargeIn == 0) {
+ enlargeIn = Math.pow(2, numBits);
+ numBits++;
+ }
+
+ if (dictionary[c]) {
+ entry = dictionary[c];
+ } else {
+ if (c === dictSize) {
+ entry = w + w.charAt(0);
+ } else {
+ return null;
+ }
+ }
+ result.push(entry);
+
+ // Add w+entry[0] to the dictionary.
+ dictionary[dictSize++] = w + entry.charAt(0);
+ enlargeIn--;
+
+ w = entry;
+
+ if (enlargeIn == 0) {
+ enlargeIn = Math.pow(2, numBits);
+ numBits++;
+ }
+
+ }
+ }
+ };
+ return LZString;
+})();
+
+if (typeof define === 'function' && define.amd) {
+ define(function () { return LZString; });
+} else if( typeof module !== 'undefined' && module != null ) {
+ module.exports = LZString
+}
\ No newline at end of file