Admin Menu Editor - Version 1.9.4

Version Description

  • Fixed another warning about get_magic_quotes_gpc() being deprecated in PHP 7.4. This instance was missed in the previous patch.
  • Added a workaround for an issue with MailPoet 3 where some menu settings didn't work on MailPoet's admin pages.
  • Added a workaround for an issue with Extended Widget Options where the "getting started" page that's added by that plugin showed up in the menu editor even though it was supposed to be hidden.
  • Reduced the amount of space used by plugin visibility settings. This change will take effect the next time you save the settings.
  • Extended the "compress menu configuration data" feature to use ZLIB compression in addition to menu data restructuring. This greatly decreases the amount of data stored in the database, but increases decompression overhead.
Download this release

Release Info

Developer whiteshadow
Plugin Icon 128x128 Admin Menu Editor
Version 1.9.4
Comparing to
See all releases

Code changes from version 1.9.3 to 1.9.4

ajax-wrapper/AjaxWrapper.php CHANGED
@@ -448,7 +448,11 @@ if (!class_exists('Ajaw_v1_Action', false)):
448
$this->get = $_GET;
449
$this->request = $_REQUEST;
450
451
- if ( function_exists('get_magic_quotes_gpc') && get_magic_quotes_gpc() ) {
452
$this->post = stripslashes_deep($this->post);
453
$this->get = stripslashes_deep($this->get);
454
}
448
$this->get = $_GET;
449
$this->request = $_REQUEST;
450
451
+ if (
452
+ version_compare(phpversion(), '7.4.0alpha1', '<')
453
+ && function_exists('get_magic_quotes_gpc')
454
+ && get_magic_quotes_gpc()
455
+ ) {
456
$this->post = stripslashes_deep($this->post);
457
$this->get = stripslashes_deep($this->get);
458
}
ajax-wrapper/README.md CHANGED
@@ -1,23 +1,74 @@
1
# AJAX Action Wrapper
2
3
- **Warning: Work in progress.** Not intended for public consumption. There is no documentation.
4
5
- This helper library makes it easier to handle AJAX requests in WordPress plugins.
6
7
- ### Goals
8
- Automate common, boring stuff.
9
- - [x] Automatically pass the `admin-ajax.php` URL and nonce to JS.
10
- - [x] Define required parameters.
11
- - [x] Define optional parameters with default values.
12
- - [x] Automatically remove "magic quotes" that WordPress adds to `$_GET`, `$_POST` and `$_REQUEST`.
13
- - [x] Encode return values as JSON.
14
- Security should be the default.
15
- - [x] Generate and verify nonces. Nonce verification is on by default, but can be disabled.
16
- - [x] Check capabilities.
17
- - [x] Verify that all required parameters are set.
18
- - [x] Validate parameter values.
19
- - [x] Set the required HTTP method.
20
- Resilience.
21
- - [ ] Lenient response parsing to work around bugs in other plugins. For example, deal with extraneous whitespace and PHP notices in AJAX responses.
22
- - [ ] Multiple versions of the library can coexist on the same site.
23
1
# AJAX Action Wrapper
2
3
+ This helper library makes it easier to handle AJAX requests in WordPress plugins. Mainly for personal use.
4
5
+ ### Example
6
+ Define action:
7
+ ```php
8
+ $exampleAction = ajaw_v1_CreateAction('ws_do_something')
9
+ ->handler(array($this, 'myAjaxCallback'))
10
+ ->requiredCap('manage_options')
11
+ ->method('post')
12
+ ->requiredParam('foo')
13
+ ->optionalParam('bar', 'default value')
14
+ ->register();
15
+ ```
16
17
+ Call from JavaScript:
18
+ ```javascript
19
+ AjawV1.getAction('ws_do_something').post(
20
+ {
21
+ 'foo': '...'
22
+ },
23
+ function(response) {
24
+ console.log(response);
25
+ }
26
+ );
27
+ ```
28
+
29
+ ### Features
30
- Automate common, boring stuff.
31
+ - [x] Automatically pass the `admin-ajax.php` URL and nonce to JS.
32
+ - [x] Define required parameters.
33
+ ```php
34
+ $builder->requiredParam('foo', 'int')
35
+ ```
36
+ - [x] Define optional parameters with default values.
37
+ ```php
38
+ $builder->optionalParam('meaningOfLife', 42, 'int')
39
+ ```
40
+ - [x] Automatically remove "magic quotes" that WordPress adds to `$_GET`, `$_POST` and `$_REQUEST`.
41
+ - [x] Encode return values as JSON.
42
- Security should be the default.
43
+ - [x] Generate and verify nonces. Nonce verification is on by default, but can be disabled.
44
+ ```php
45
+ $builder->withoutNonce()
46
+ ```
47
+ - [x] Check capabilities.
48
+ ```php
49
+ $builder->requiredCap('manage_options');
50
+ ```
51
+ - [x] Verify that all required parameters are set.
52
+ - [x] Validate parameter values.
53
+ ```php
54
+ $builder->optionalParam('things', 1, 'int', function($value) {
55
+ if ($value > 10) {
56
+ return new WP_Error(
57
+ 'excessive_things',
58
+ 'Too many things!',
59
+ 400 //HTTP status code.
60
+ );
61
+ }
62
+ })
63
+ ```
64
+ - [x] Set the required HTTP method.
65
+ ```php
66
+ $builder->method('post')
67
+ ```
68
- Resilience.
69
+ - [ ] Lenient response parsing to work around bugs in other plugins. For example, deal with extraneous whitespace and PHP notices in AJAX responses.
70
+ - [x] Multiple versions of the library can coexist on the same site.
71
+
72
+ ### Why not use the REST API instead?
73
74
+ Backwards compatibility. In theory, this library should be compatible with WP 4.1+.
ajax-wrapper/ajax-action-wrapper.d.ts CHANGED
@@ -2,8 +2,8 @@
2
3
declare namespace AjawV1 {
4
interface RequestParams { [name: string]: any }
5
- interface SuccessCallback { (data, textStatus: string, jqXHR): string }
6
- interface ErrorCallback { (data, textStatus: string, jqXHR, errorThrown): string }
7
8
class AjawAjaxAction {
9
get(params?: RequestParams, success?: SuccessCallback, error?: ErrorCallback): void;
2
3
declare namespace AjawV1 {
4
interface RequestParams { [name: string]: any }
5
+ interface SuccessCallback { (data, textStatus: string, jqXHR): void }
6
+ interface ErrorCallback { (data, textStatus: string, jqXHR, errorThrown): void }
7
8
class AjawAjaxAction {
9
get(params?: RequestParams, success?: SuccessCallback, error?: ErrorCallback): void;
css/_boxes.scss CHANGED
@@ -1,11 +1,12 @@
1
$amePostboxBorderColor: #ccd0d4; //Was #e5e5e5 before WP 5.3.
2
3
@mixin ame-emulated-postbox($toggleWidth: 36px, $horizontalPadding: 12px) {
4
$borderColor: $amePostboxBorderColor;
5
$headerBackground: #fff;
6
7
position: relative;
8
- box-shadow: 0 1px 1px rgba(0, 0, 0, 0.04);
9
background: $headerBackground;
10
11
margin-bottom: 20px;
1
$amePostboxBorderColor: #ccd0d4; //Was #e5e5e5 before WP 5.3.
2
+ $amePostboxShadow: 0 1px 1px rgba(0, 0, 0, 0.04);
3
4
@mixin ame-emulated-postbox($toggleWidth: 36px, $horizontalPadding: 12px) {
5
$borderColor: $amePostboxBorderColor;
6
$headerBackground: #fff;
7
8
position: relative;
9
+ box-shadow: $amePostboxShadow;
10
background: $headerBackground;
11
12
margin-bottom: 20px;
images/reset-permissions.png CHANGED
Binary file
includes/ame-utils.php CHANGED
@@ -15,20 +15,20 @@ class ameUtils {
15
* @return mixed
16
*/
17
public static function get($array, $path, $default = null, $separator = '.') {
18
- if (is_string($path)) {
19
$path = explode($separator, $path);
20
}
21
- if (empty($path)) {
22
return $default;
23
}
24
25
//Follow the $path into $input as far as possible.
26
$currentValue = $array;
27
$pathExists = true;
28
- foreach($path as $node) {
29
- if (is_array($currentValue) && array_key_exists($node, $currentValue)) {
30
$currentValue = $currentValue[$node];
31
- } else if (is_object($currentValue) && property_exists($currentValue, $node)) {
32
$currentValue = $currentValue->$node;
33
} else {
34
$pathExists = false;
@@ -36,7 +36,7 @@ class ameUtils {
36
}
37
}
38
39
- if ($pathExists) {
40
return $currentValue;
41
}
42
return $default;
@@ -59,9 +59,91 @@ class ameUtils {
59
$fileName = ltrim($fileName, '/');
60
61
$segments = explode('/', $fileName, 2);
62
- if ((count($segments) > 1) && ($segments[0] !== '')) {
63
return $segments[0];
64
}
65
return null;
66
}
67
}
15
* @return mixed
16
*/
17
public static function get($array, $path, $default = null, $separator = '.') {
18
+ if ( is_string($path) ) {
19
$path = explode($separator, $path);
20
}
21
+ if ( empty($path) ) {
22
return $default;
23
}
24
25
//Follow the $path into $input as far as possible.
26
$currentValue = $array;
27
$pathExists = true;
28
+ foreach ($path as $node) {
29
+ if ( is_array($currentValue) && array_key_exists($node, $currentValue) ) {
30
$currentValue = $currentValue[$node];
31
+ } else if ( is_object($currentValue) && property_exists($currentValue, $node) ) {
32
$currentValue = $currentValue->$node;
33
} else {
34
$pathExists = false;
36
}
37
}
38
39
+ if ( $pathExists ) {
40
return $currentValue;
41
}
42
return $default;
59
$fileName = ltrim($fileName, '/');
60
61
$segments = explode('/', $fileName, 2);
62
+ if ( (count($segments) > 1) && ($segments[0] !== '') ) {
63
return $segments[0];
64
}
65
return null;
66
}
67
+ }
68
+
69
+ class ameFileLock {
70
+ protected $fileName;
71
+ protected $handle = null;
72
+
73
+ public function __construct($fileName) {
74
+ $this->fileName = $fileName;
75
+ }
76
+
77
+ public function acquire($timeout = null) {
78
+ if ( $this->handle !== null ) {
79
+ throw new RuntimeException('Cannot acquire a lock that is already held.');
80
+ }
81
+ if ( !function_exists('flock') ) {
82
+ return false;
83
+ }
84
+
85
+ $this->handle = @fopen(__FILE__, 'r');
86
+ if ( !$this->handle ) {
87
+ $this->handle = null;
88
+ return false;
89
+ }
90
+
91
+ $success = @flock($this->handle, LOCK_EX | LOCK_NB, $wouldBlock);
92
+
93
+ if ( !$success && $wouldBlock && ($timeout !== null) ) {
94
+ $timeout = max(min($timeout, 0.1), 600);
95
+ $endTime = microtime(true) + $timeout;
96
+ //Wait for a short, random time and try again.
97
+ do {
98
+ $canWaitMore = $this->waitRandom($endTime);
99
+ $success = @flock($this->handle, LOCK_EX | LOCK_NB, $wouldBlock);
100
+ } while (!$success && $wouldBlock && $canWaitMore);
101
+ }
102
+
103
+ if ( !$success ) {
104
+ fclose($this->handle);
105
+ $this->handle = null;
106
+ return false;
107
+ }
108
+ return true;
109
+ }
110
+
111
+ public function release() {
112
+ if ( $this->handle !== null ) {
113
+ @flock($this->handle, LOCK_UN);
114
+ fclose($this->handle);
115
+ $this->handle = null;
116
+ }
117
+ }
118
+
119
+ /**
120
+ * Wait for a random interval without going over $endTime.
121
+ *
122
+ * @param float|int $endTime Unix timestamp.
123
+ * @return bool TRUE if there's still time until $endTime, FALSE otherwise.
124
+ */
125
+ protected function waitRandom($endTime) {
126
+ $now = microtime(true);
127
+ if ( $now >= $endTime ) {
128
+ return false;
129
+ }
130
+
131
+ $delayMs = rand(80, 300);
132
+ $remainingTimeMs = ($endTime - $now) * 1000;
133
+ if ( $delayMs < $remainingTimeMs ) {
134
+ usleep($delayMs * 1000);
135
+ return true;
136
+ } else {
137
+ usleep($remainingTimeMs * 1000);
138
+ return false;
139
+ }
140
+ }
141
+
142
+ public static function create($fileName) {
143
+ return new self($fileName);
144
+ }
145
+
146
+ public function __destruct() {
147
+ $this->release();
148
+ }
149
}
includes/editor-page.php CHANGED
@@ -27,6 +27,7 @@ $icons = array(
27
foreach($icons as $name => $url) {
28
$icons[$name] = $images_url . $url;
29
}
30
31
$hide_button_extra_tooltip = 'When "All" is selected, this will hide the menu from everyone except the current user'
32
. ($is_multisite ? ' and Super Admin' : '') . '.';
@@ -144,18 +145,7 @@ function ame_output_sort_buttons($icons) {
144
}
145
?>
146
147
- <?php if ( $is_pro_version ): ?>
148
- <div class="ws_separator">&nbsp;</div>
149
-
150
- <a id='ws_toggle_all_menus' class='ws_button' href='javascript:void(0)'
151
- title='Toggle all menus for the selected role'><img src='<?php echo $icons['toggle-all']; ?>' alt="Toggle all" /></a>
152
-
153
- <a id='ws_copy_role_permissions' class='ws_button' href='javascript:void(0)'
154
- title='Copy all menu permissions from one role to another'><img src='<?php echo $icons['copy-permissions']; ?>' alt="Copy permissions" /></a>
155
-
156
- <div class="ws_separator">&nbsp;</div>
157
- <?php endif; ?>
158
-
159
<div class="clear"></div>
160
</div>
161
</div>
27
foreach($icons as $name => $url) {
28
$icons[$name] = $images_url . $url;
29
}
30
+ $icons = apply_filters('admin_menu_editor-toolbar_icons', $icons, $images_url);
31
32
$hide_button_extra_tooltip = 'When "All" is selected, this will hide the menu from everyone except the current user'
33
. ($is_multisite ? ' and Super Admin' : '') . '.';
145
}
146
?>
147
148
+ <?php do_action('admin_menu_editor-toolbar_row_2', $icons); ?>
149
<div class="clear"></div>
150
</div>
151
</div>
includes/menu-editor-core.php CHANGED
@@ -245,6 +245,8 @@ class WPMenuEditor extends MenuEd_ShadowPluginFramework {
245
'admin.php?page=WPCW_showPage_UserCourseAccess' => true,
246
'admin.php?page=WPCW_showPage_UserProgess' => true,
247
'admin.php?page=WPCW_showPage_UserProgess_quizAnswers' => true,
248
);
249
250
//AJAXify screen options
@@ -322,6 +324,7 @@ class WPMenuEditor extends MenuEd_ShadowPluginFramework {
322
$this->import_settings();
323
$should_save_options = true;
324
}
325
326
//Track first install time.
327
if ( !isset($this->options['first_install_time']) ) {
@@ -353,6 +356,9 @@ class WPMenuEditor extends MenuEd_ShadowPluginFramework {
353
add_action('admin_notices', array($this, 'display_security_log'));
354
}
355
356
if ( did_action('plugins_loaded') ) {
357
$this->load_modules();
358
} else {
@@ -840,7 +846,7 @@ class WPMenuEditor extends MenuEd_ShadowPluginFramework {
840
}
841
842
//Any capability that's assigned to a role probably isn't a meta capability.
843
- $allRealCaps = ameRoleUtils::get_all_capabilities();
844
//Similarly, capabilities that are directly assigned to users are probably real.
845
foreach($users as $user) {
846
$allRealCaps = array_merge($allRealCaps, $user['capabilities']);
@@ -2569,7 +2575,7 @@ class WPMenuEditor extends MenuEd_ShadowPluginFramework {
2569
$editor_data['custom_menu_js'] = ameMenu::to_json($custom_menu);
2570
2571
//Create a list of all known capabilities and roles. Used for the drop-down list on the access field.
2572
- $all_capabilities = ameRoleUtils::get_all_capabilities();
2573
//"level_X" capabilities are deprecated so we don't want people using them.
2574
//This would look better with array_filter() and an anonymous function as a callback.
2575
for($level = 0; $level <= 10; $level++){
@@ -3851,6 +3857,29 @@ class WPMenuEditor extends MenuEd_ShadowPluginFramework {
3851
}
3852
}
3853
3854
/**
3855
* As of WP 3.5, the Links Manager is hidden by default. It's only visible if the user has existing links
3856
* or they choose to enable it by installing the Links Manager plugin.
245
'admin.php?page=WPCW_showPage_UserCourseAccess' => true,
246
'admin.php?page=WPCW_showPage_UserProgess' => true,
247
'admin.php?page=WPCW_showPage_UserProgess_quizAnswers' => true,
248
+ //Extended Widget Options
249
+ 'index.php?page=extended-widget-opts-getting-started' => true,
250
);
251
252
//AJAXify screen options
324
$this->import_settings();
325
$should_save_options = true;
326
}
327
+ $this->zlib_compression = $this->options['compress_custom_menu'];
328
329
//Track first install time.
330
if ( !isset($this->options['first_install_time']) ) {
356
add_action('admin_notices', array($this, 'display_security_log'));
357
}
358
359
+ //Compatibility fix for MailPoet 3.
360
+ $this->apply_mailpoet_compat_fix();
361
+
362
if ( did_action('plugins_loaded') ) {
363
$this->load_modules();
364
} else {
846
}
847
848
//Any capability that's assigned to a role probably isn't a meta capability.
849
+ $allRealCaps = ameRoleUtils::get_all_capabilities(true);
850
//Similarly, capabilities that are directly assigned to users are probably real.
851
foreach($users as $user) {
852
$allRealCaps = array_merge($allRealCaps, $user['capabilities']);
2575
$editor_data['custom_menu_js'] = ameMenu::to_json($custom_menu);
2576
2577
//Create a list of all known capabilities and roles. Used for the drop-down list on the access field.
2578
+ $all_capabilities = ameRoleUtils::get_all_capabilities(is_multisite());
2579
//"level_X" capabilities are deprecated so we don't want people using them.
2580
//This would look better with array_filter() and an anonymous function as a callback.
2581
for($level = 0; $level <= 10; $level++){
3857
}
3858
}
3859
3860
+ /**
3861
+ * Compatibility fix for MailPoet 3. Last tested with MailPoet 3.44.0.
3862
+ *
3863
+ * MailPoet deliberately removes all third-party stylesheets from its admin pages.
3864
+ * As a result, some AME features that use stylesheets - like custom menu icons and admin
3865
+ * menu colors - don't work on those pages. Let's fix that by whitelisting our styles.
3866
+ */
3867
+ private function apply_mailpoet_compat_fix() {
3868
+ add_filter('mailpoet_conflict_resolver_whitelist_style', array($this, '_whitelist_ame_styles_for_mailpoet'));
3869
+ }
3870
+
3871
+ /**
3872
+ * @internal
3873
+ * @param array $styles
3874
+ * @return array
3875
+ */
3876
+ public function _whitelist_ame_styles_for_mailpoet($styles) {
3877
+ $styles[] = 'ame_output_menu_color_css';
3878
+ $styles[] = 'font-awesome\.css';
3879
+ $styles[] = 'force-dashicons\.css';
3880
+ return $styles;
3881
+ }
3882
+
3883
/**
3884
* As of WP 3.5, the Links Manager is hidden by default. It's only visible if the user has existing links
3885
* or they choose to enable it by installing the Links Manager plugin.
includes/role-utils.php CHANGED
@@ -6,11 +6,19 @@ class ameRoleUtils {
6
* @param bool $include_multisite_caps
7
* @return array Associative array with capability names as keys
8
*/
9
- public static function get_all_capabilities($include_multisite_caps = true){
10
//Cache the results.
11
- static $capabilities = null;
12
- if ( isset($capabilities) ) {
13
- return $capabilities;
14
}
15
16
$wp_roles = self::get_roles();
@@ -22,6 +30,7 @@ class ameRoleUtils {
22
$capabilities = array_merge($capabilities, $role['capabilities']);
23
}
24
}
25
26
//Add multisite-specific capabilities (not listed in any roles in WP 3.0)
27
if ($include_multisite_caps) {
@@ -34,6 +43,7 @@ class ameRoleUtils {
34
'manage_network_plugins' => 1,
35
);
36
$capabilities = array_merge($capabilities, $multisite_caps);
37
}
38
39
return $capabilities;
6
* @param bool $include_multisite_caps
7
* @return array Associative array with capability names as keys
8
*/
9
+ public static function get_all_capabilities($include_multisite_caps = null){
10
+ if ( $include_multisite_caps === null ) {
11
+ $include_multisite_caps = is_multisite();
12
+ }
13
+
14
//Cache the results.
15
+ static $regular_cache = null, $multisite_cache = null;
16
+ if ( $include_multisite_caps ) {
17
+ if ( isset($multisite_cache) ) {
18
+ return $multisite_cache;
19
+ }
20
+ } else if ( isset($regular_cache) ) {
21
+ return $regular_cache;
22
}
23
24
$wp_roles = self::get_roles();
30
$capabilities = array_merge($capabilities, $role['capabilities']);
31
}
32
}
33
+ $regular_cache = $capabilities;
34
35
//Add multisite-specific capabilities (not listed in any roles in WP 3.0)
36
if ($include_multisite_caps) {
43
'manage_network_plugins' => 1,
44
);
45
$capabilities = array_merge($capabilities, $multisite_caps);
46
+ $multisite_cache = $capabilities;
47
}
48
49
return $capabilities;
includes/shadow_plugin_framework.php CHANGED
@@ -22,7 +22,8 @@ class MenuEd_ShadowPluginFramework {
22
public $option_name = ''; //should be set or overridden by the plugin
23
protected $defaults = array(); //should be set or overridden by the plugin
24
protected $sitewide_options = false; //WPMU only : save the setting in a site-wide option
25
- protected $serialize_with_json = false; //Use the JSON format for option storage
26
27
public $plugin_file = ''; //Filename of the plugin.
28
public $plugin_basename = ''; //Basename of the plugin, as returned by plugin_basename().
@@ -120,7 +121,18 @@ class MenuEd_ShadowPluginFramework {
120
} else {
121
$this->options = get_option($option_name);
122
}
123
-
124
if ( $this->serialize_with_json || is_string($this->options) ){
125
$this->options = $this->json_decode($this->options, true);
126
}
@@ -146,7 +158,12 @@ class MenuEd_ShadowPluginFramework {
146
if ( $this->serialize_with_json ){
147
$stored_options = $this->json_encode($stored_options);
148
}
149
-
150
if ( $this->sitewide_options && is_multisite() ) {
151
return self::atomic_update_site_option($this->option_name, $stored_options);
152
} else {
22
public $option_name = ''; //should be set or overridden by the plugin
23
protected $defaults = array(); //should be set or overridden by the plugin
24
protected $sitewide_options = false; //WPMU only : save the setting in a site-wide option
25
+ protected $serialize_with_json = false; //Use the JSON format for option storage
26
+ protected $zlib_compression = false;
27
28
public $plugin_file = ''; //Filename of the plugin.
29
public $plugin_basename = ''; //Basename of the plugin, as returned by plugin_basename().
121
} else {
122
$this->options = get_option($option_name);
123
}
124
+
125
+ $prefix = 'gzcompress:';
126
+ if (
127
+ is_string($this->options)
128
+ && (substr($this->options, 0, strlen($prefix)) === $prefix)
129
+ && function_exists('gzuncompress')
130
+ ) {
131
+ //TODO: Maybe this would be faster if we stored the flag separately?
132
+ /** @noinspection PhpComposerExtensionStubsInspection */
133
+ $this->options = unserialize(gzuncompress(base64_decode(substr($this->options, strlen($prefix)))));
134
+ }
135
+
136
if ( $this->serialize_with_json || is_string($this->options) ){
137
$this->options = $this->json_decode($this->options, true);
138
}
158
if ( $this->serialize_with_json ){
159
$stored_options = $this->json_encode($stored_options);
160
}
161
+
162
+ if ( $this->zlib_compression && function_exists('gzcompress') ) {
163
+ /** @noinspection PhpComposerExtensionStubsInspection */
164
+ $stored_options = 'gzcompress:' . base64_encode(gzcompress(serialize($stored_options)));
165
+ }
166
+
167
if ( $this->sitewide_options && is_multisite() ) {
168
return self::atomic_update_site_option($this->option_name, $stored_options);
169
} else {
js/actor-manager.js CHANGED
@@ -1,4 +1,5 @@
1
/// <reference path="lodash-3.10.d.ts" />
2
/// <reference path="common.d.ts" />
3
var __extends = (this && this.__extends) || (function () {
4
var extendStatics = function (d, b) {
@@ -42,7 +43,7 @@ var AmeBaseActor = /** @class */ (function () {
42
return null;
43
};
44
AmeBaseActor.getActorSpecificity = function (actorId) {
45
- var actorType = actorId.substring(0, actorId.indexOf(':')), specificity = 0;
46
switch (actorType) {
47
case 'role':
48
specificity = 1;
@@ -357,6 +358,18 @@ var AmeActorManager = /** @class */ (function () {
357
delete context[actor][capability];
358
}
359
};
360
/**
361
* Remove redundant granted capabilities.
362
*
1
/// <reference path="lodash-3.10.d.ts" />
2
+ /// <reference path="knockout.d.ts" />
3
/// <reference path="common.d.ts" />
4
var __extends = (this && this.__extends) || (function () {
5
var extendStatics = function (d, b) {
43
return null;
44
};
45
AmeBaseActor.getActorSpecificity = function (actorId) {
46
+ var actorType = actorId.substring(0, actorId.indexOf(':')), specificity;
47
switch (actorType) {
48
case 'role':
49
specificity = 1;
358
delete context[actor][capability];
359
}
360
};
361
+ /**
362
+ * Reset all capabilities granted to an actor.
363
+ * @param actor
364
+ * @return boolean TRUE if anything was reset or FALSE if the actor didn't have any granted capabilities.
365
+ */
366
+ AmeActorManager.prototype.resetActorCaps = function (actor) {
367
+ if (AmeActorManager._.has(this.grantedCapabilities, actor)) {
368
+ delete this.grantedCapabilities[actor];
369
+ return true;
370
+ }
371
+ return false;
372
+ };
373
/**
374
* Remove redundant granted capabilities.
375
*
js/actor-manager.ts CHANGED
@@ -1,4 +1,5 @@
1
/// <reference path="lodash-3.10.d.ts" />
2
/// <reference path="common.d.ts" />
3
4
declare let wsAmeActorData: any;
@@ -58,7 +59,7 @@ abstract class AmeBaseActor implements IAmeActor {
58
59
static getActorSpecificity(actorId: string) {
60
let actorType = actorId.substring(0, actorId.indexOf(':')),
61
- specificity = 0;
62
switch (actorType) {
63
case 'role':
64
specificity = 1;
@@ -476,6 +477,19 @@ class AmeActorManager implements AmeActorManagerInterface {
476
}
477
}
478
479
/**
480
* Remove redundant granted capabilities.
481
*
1
/// <reference path="lodash-3.10.d.ts" />
2
+ /// <reference path="knockout.d.ts" />
3
/// <reference path="common.d.ts" />
4
5
declare let wsAmeActorData: any;
59
60
static getActorSpecificity(actorId: string) {
61
let actorType = actorId.substring(0, actorId.indexOf(':')),
62
+ specificity;
63
switch (actorType) {
64
case 'role':
65
specificity = 1;
477
}
478
}
479
480
+ /**
481
+ * Reset all capabilities granted to an actor.
482
+ * @param actor
483
+ * @return boolean TRUE if anything was reset or FALSE if the actor didn't have any granted capabilities.
484
+ */
485
+ resetActorCaps(actor: string): boolean {
486
+ if (AmeActorManager._.has(this.grantedCapabilities, actor)) {
487
+ delete this.grantedCapabilities[actor];
488
+ return true;
489
+ }
490
+ return false;
491
+ }
492
+
493
/**
494
* Remove redundant granted capabilities.
495
*
js/common.d.ts CHANGED
@@ -1,3 +1,6 @@
1
interface AmeDictionary<T> {
2
[mapKey: string] : T;
3
- }
1
interface AmeDictionary<T> {
2
[mapKey: string] : T;
3
+ }
4
+
5
+ // noinspection JSUnusedGlobalSymbols
6
+ type KeysMatchingType<T, V> = { [K in keyof T]: T[K] extends V ? K : never }[keyof T];
js/knockout.d.ts CHANGED
@@ -1,631 +1,1064 @@
1
- // Type definitions for Knockout v3.2.0
2
- // Project: http://knockoutjs.com
3
- // Definitions by: Boris Yankov <https://github.com/borisyankov/>, Igor Oleinikov <https://github.com/Igorbek/>, Clément Bourgeois <https://github.com/moonpyk/>
4
- // Definitions: https://github.com/borisyankov/DefinitelyTyped
5
-
6
-
7
- interface KnockoutSubscribableFunctions<T> {
8
- [key: string]: KnockoutBindingHandler;
9
-
10
- notifySubscribers(valueToWrite?: T, event?: string): void;
11
- }
12
-
13
- interface KnockoutComputedFunctions<T> {
14
- [key: string]: KnockoutBindingHandler;
15
- }
16
-
17
- interface KnockoutObservableFunctions<T> {
18
- [key: string]: KnockoutBindingHandler;
19
-
20
- equalityComparer(a: any, b: any): boolean;
21
- }
22
-
23
- interface KnockoutObservableArrayFunctions<T> {
24
- // General Array functions
25
- indexOf(searchElement: T, fromIndex?: number): number;
26
- slice(start: number, end?: number): T[];
27
- splice(start: number): T[];
28
- splice(start: number, deleteCount: number, ...items: T[]): T[];
29
- pop(): T;
30
- push(...items: T[]): void;
31
- shift(): T;
32
- unshift(...items: T[]): number;
33
- reverse(): KnockoutObservableArray<T>;
34
- sort(): KnockoutObservableArray<T>;
35
- sort(compareFunction: (left: T, right: T) => number): KnockoutObservableArray<T>;
36
-
37
- // Ko specific
38
- [key: string]: KnockoutBindingHandler;
39
-
40
- replace(oldItem: T, newItem: T): void;
41
-
42
- remove(item: T): T[];
43
- remove(removeFunction: (item: T) => boolean): T[];
44
- removeAll(items: T[]): T[];
45
- removeAll(): T[];
46
-
47
- destroy(item: T): void;
48
- destroy(destroyFunction: (item: T) => boolean): void;
49
- destroyAll(items: T[]): void;
50
- destroyAll(): void;
51
- }
52
-
53
- interface KnockoutSubscribableStatic {
54
- fn: KnockoutSubscribableFunctions<any>;
55
-
56
- new <T>(): KnockoutSubscribable<T>;
57
- }
58
-
59
- interface KnockoutSubscription {
60
- dispose(): void;
61
- }
62
-
63
- interface KnockoutSubscribable<T> extends KnockoutSubscribableFunctions<T> {
64
- subscribe(callback: (newValue: T) => void, target?: any, event?: string): KnockoutSubscription;
65
- subscribe<TEvent>(callback: (newValue: TEvent) => void, target: any, event: string): KnockoutSubscription;
66
- extend(requestedExtenders: { [key: string]: any; }): KnockoutSubscribable<T>;
67
- getSubscriptionsCount(): number;
68
- }
69
-
70
- interface KnockoutComputedStatic {
71
- fn: KnockoutComputedFunctions<any>;
72
-
73
- <T>(): KnockoutComputed<T>;
74
- <T>(func: () => T, context?: any, options?: any): KnockoutComputed<T>;
75
- <T>(def: KnockoutComputedDefine<T>, context?: any): KnockoutComputed<T>;
76
- }
77
-
78
- interface KnockoutComputed<T> extends KnockoutObservable<T>, KnockoutComputedFunctions<T> {
79
- fn: KnockoutComputedFunctions<any>;
80
-
81
- dispose(): void;
82
- isActive(): boolean;
83
- getDependenciesCount(): number;
84
- extend(requestedExtenders: { [key: string]: any; }): KnockoutComputed<T>;
85
- }
86
-
87
- interface KnockoutObservableArrayStatic {
88
- fn: KnockoutObservableArrayFunctions<any>;
89
-
90
- <T>(value?: T[]): KnockoutObservableArray<T>;
91
- }
92
-
93
- interface KnockoutObservableArray<T> extends KnockoutObservable<T[]>, KnockoutObservableArrayFunctions<T> {
94
- extend(requestedExtenders: { [key: string]: any; }): KnockoutObservableArray<T>;
95
- }
96
-
97
- interface KnockoutObservableStatic {
98
- fn: KnockoutObservableFunctions<any>;
99
-
100
- <T>(value?: T): KnockoutObservable<T>;
101
- }
102
-
103
- interface KnockoutObservable<T> extends KnockoutSubscribable<T>, KnockoutObservableFunctions<T> {
104
- (): T;
105
- (value: T): void;
106
-
107
- peek(): T;
108
- valueHasMutated?:{(): void;};
109
- valueWillMutate?:{(): void;};
110
- extend(requestedExtenders: { [key: string]: any; }): KnockoutObservable<T>;
111
- }
112
-
113
- interface KnockoutComputedDefine<T> {
114
- read(): T;
115
- write? (value: T): void;
116
- disposeWhenNodeIsRemoved?: Node;
117
- disposeWhen? (): boolean;
118
- owner?: any;
119
- deferEvaluation?: boolean;
120
- pure?: boolean;
121
- }
122
-
123
- interface KnockoutBindingContext {
124
- $parent: any;
125
- $parents: any[];
126
- $root: any;
127
- $data: any;
128
- $rawData: any | KnockoutObservable<any>;
129
- $index?: KnockoutObservable<number>;
130
- $parentContext?: KnockoutBindingContext;
131
- $component: any;
132
- $componentTemplateNodes: Node[];
133
-
134
- extend(properties: any): any;
135
- createChildContext(dataItemOrAccessor: any, dataItemAlias?: any, extendCallback?: Function): any;
136
- }
137
-
138
- interface KnockoutAllBindingsAccessor {
139
- (): any;
140
- get(name: string): any;
141
- has(name: string): boolean;
142
- }
143
-
144
- interface KnockoutBindingHandler {
145
- after?: Array<string>;
146
- init?: (element: any, valueAccessor: () => any, allBindingsAccessor?: KnockoutAllBindingsAccessor, viewModel?: any, bindingContext?: KnockoutBindingContext) => void | { controlsDescendantBindings: boolean; };
147
- update?: (element: any, valueAccessor: () => any, allBindingsAccessor?: KnockoutAllBindingsAccessor, viewModel?: any, bindingContext?: KnockoutBindingContext) => void;
148
- options?: any;
149
- preprocess?: (value: string, name: string, addBindingCallback?: (name: string, value: string) => void) => string;
150
- }
151
-
152
- interface KnockoutBindingHandlers {
153
- [bindingHandler: string]: KnockoutBindingHandler;
154
-
155
- // Controlling text and appearance
156
- visible: KnockoutBindingHandler;
157
- text: KnockoutBindingHandler;
158
- html: KnockoutBindingHandler;
159
- css: KnockoutBindingHandler;
160
- style: KnockoutBindingHandler;
161
- attr: KnockoutBindingHandler;
162
-
163
- // Control Flow
164
- foreach: KnockoutBindingHandler;
165
- if: KnockoutBindingHandler;
166
- ifnot: KnockoutBindingHandler;
167
- with: KnockoutBindingHandler;
168
-
169
- // Working with form fields
170
- click: KnockoutBindingHandler;
171
- event: KnockoutBindingHandler;
172
- submit: KnockoutBindingHandler;
173
- enable: KnockoutBindingHandler;
174
- disable: KnockoutBindingHandler;
175
- value: KnockoutBindingHandler;
176
- textInput: KnockoutBindingHandler;
177
- hasfocus: KnockoutBindingHandler;
178
- checked: KnockoutBindingHandler;
179
- options: KnockoutBindingHandler;
180
- selectedOptions: KnockoutBindingHandler;
181
- uniqueName: KnockoutBindingHandler;
182
-
183
- // Rendering templates
184
- template: KnockoutBindingHandler;
185
-
186
- // Components (new for v3.2)
187
- component: KnockoutBindingHandler;
188
- }
189
-
190
- interface KnockoutMemoization {
191
- memoize(callback: () => string): string;
192
- unmemoize(memoId: string, callbackParams: any[]): boolean;
193
- unmemoizeDomNodeAndDescendants(domNode: any, extraCallbackParamsArray: any[]): boolean;
194
- parseMemoText(memoText: string): string;
195
- }
196
-
197
- interface KnockoutVirtualElement {}
198
-
199
- interface KnockoutVirtualElements {
200
- allowedBindings: { [bindingName: string]: boolean; };
201
- emptyNode(node: KnockoutVirtualElement ): void;
202
- firstChild(node: KnockoutVirtualElement ): KnockoutVirtualElement;
203
- insertAfter( container: KnockoutVirtualElement, nodeToInsert: Node, insertAfter: Node ): void;
204
- nextSibling(node: KnockoutVirtualElement): Node;
205
- prepend(node: KnockoutVirtualElement, toInsert: Node ): void;
206
- setDomNodeChildren(node: KnockoutVirtualElement, newChildren: { length: number;[index: number]: Node; } ): void;
207
- childNodes(node: KnockoutVirtualElement ): Node[];
208
- }
209
-
210
- interface KnockoutExtenders {
211
- throttle(target: any, timeout: number): KnockoutComputed<any>;
212
- notify(target: any, notifyWhen: string): any;
213
-
214
- rateLimit(target: any, timeout: number): any;
215
- rateLimit(target: any, options: { timeout: number; method?: string; }): any;
216
-
217
- trackArrayChanges(target: any): any;
218
- }
219
-
220
- //
221
- // NOTE TO MAINTAINERS AND CONTRIBUTORS : pay attention to only include symbols that are
222
- // publicly exported in the minified version of ko, without that you can give the false
223
- // impression that some functions will be available in production builds.
224
- //
225
- interface KnockoutUtils {
226
- //////////////////////////////////
227
- // utils.domData.js
228
- //////////////////////////////////
229
-
230
- domData: {
231
- get (node: Element, key: string): any;
232
-
233
- set (node: Element, key: string, value: any): void;
234
-
235
- getAll(node: Element, createIfNotFound: boolean): any;
236
-
237
- clear(node: Element): boolean;
238
- };
239
-
240
- //////////////////////////////////
241
- // utils.domNodeDisposal.js
242
- //////////////////////////////////
243
-
244
- domNodeDisposal: {
245
- addDisposeCallback(node: Element, callback: Function): void;
246
-
247
- removeDisposeCallback(node: Element, callback: Function): void;
248
-
249
- cleanNode(node: Node): Element;
250
-
251
- removeNode(node: Node): void;
252
- };
253
-
254
- addOrRemoveItem<T>(array: T[] | KnockoutObservable<T>, value: T, included: T): void;
255
-
256
- arrayFilter<T>(array: T[], predicate: (item: T) => boolean): T[];
257
-
258
- arrayFirst<T>(array: T[], predicate: (item: T) => boolean, predicateOwner?: any): T;
259
-
260
- arrayForEach<T>(array: T[], action: (item: T, index: number) => void): void;
261
-
262
- arrayGetDistinctValues<T>(array: T[]): T[];
263
-
264
- arrayIndexOf<T>(array: T[], item: T): number;
265
-
266
- arrayMap<T, U>(array: T[], mapping: (item: T) => U): U[];
267
-
268
- arrayPushAll<T>(array: T[] | KnockoutObservableArray<T>, valuesToPush: T[]): T[];
269
-
270
- arrayRemoveItem(array: any[], itemToRemove: any): void;
271
-
272
- compareArrays<T>(a: T[], b: T[]): Array<KnockoutArrayChange<T>>;
273
-
274
- extend(target: Object, source: Object): Object;
275
-
276
- fieldsIncludedWithJsonPost: any[];
277
-
278
- getFormFields(form: any, fieldName: string): any[];
279
-
280
- objectForEach(obj: any, action: (key: any, value: any) => void): void;
281
-
282
- parseHtmlFragment(html: string): any[];
283
-
284
- parseJson(jsonString: string): any;
285
-
286
- postJson(urlOrForm: any, data: any, options: any): void;
287
-
288
- peekObservable<T>(value: KnockoutObservable<T>): T;
289
-
290
- range(min: any, max: any): any;
291
-
292
- registerEventHandler(element: any, eventType: any, handler: Function): void;
293
-
294
- setHtml(node: Element, html: () => string): void;
295
-
296
- setHtml(node: Element, html: string): void;
297
-
298
- setTextContent(element: any, textContent: string | KnockoutObservable<string>): void;
299
-
300
- stringifyJson(data: any, replacer?: Function, space?: string): string;
301
-
302
- toggleDomNodeCssClass(node: any, className: string, shouldHaveClass: boolean): void;
303
-
304
- triggerEvent(element: any, eventType: any): void;
305
-
306
- unwrapObservable<T>(value: KnockoutObservable<T> | T): T;
307
-
308
- // NOT PART OF THE MINIFIED API SURFACE (ONLY IN knockout-{version}.debug.js) https://github.com/SteveSanderson/knockout/issues/670
309
- // forceRefresh(node: any): void;
310
- // ieVersion: number;
311
- // isIe6: boolean;
312
- // isIe7: boolean;
313
- // jQueryHtmlParse(html: string): any[];
314
- // makeArray(arrayLikeObject: any): any[];
315
- // moveCleanedNodesToContainerElement(nodes: any[]): HTMLElement;
316
- // replaceDomNodes(nodeToReplaceOrNodeArray: any, newNodesArray: any[]): void;
317
- // setDomNodeChildren(domNode: any, childNodes: any[]): void;
318
- // setElementName(element: any, name: string): void;
319
- // setOptionNodeSelectionState(optionNode: any, isSelected: boolean): void;
320
- // simpleHtmlParse(html: string): any[];
321
- // stringStartsWith(str: string, startsWith: string): boolean;
322
- // stringTokenize(str: string, delimiter: string): string[];
323
- // stringTrim(str: string): string;
324
- // tagNameLower(element: any): string;
325
- }
326
-
327
- interface KnockoutArrayChange<T> {
328
- status: string;
329
- value: T;
330
- index: number;
331
- moved?: number;
332
- }
333
-
334
- //////////////////////////////////
335
- // templateSources.js
336
- //////////////////////////////////
337
-
338
- interface KnockoutTemplateSourcesDomElement {
339
- text(): any;
340
- text(value: any): void;
341
-
342
- data(key: string): any;
343
- data(key: string, value: any): any;
344
- }
345
-
346
- interface KnockoutTemplateAnonymous extends KnockoutTemplateSourcesDomElement {
347
- nodes(): any;
348
- nodes(value: any): void;
349
- }
350
-
351
- interface KnockoutTemplateSources {
352
-
353
- domElement: {
354
- prototype: KnockoutTemplateSourcesDomElement
355
- new (element: Element): KnockoutTemplateSourcesDomElement
356
- };
357
-
358
- anonymousTemplate: {
359
- prototype: KnockoutTemplateAnonymous;
360
- new (element: Element): KnockoutTemplateAnonymous;
361
- };
362
- }
363
-
364
- //////////////////////////////////
365
- // nativeTemplateEngine.js
366
- //////////////////////////////////
367
-
368
- interface KnockoutNativeTemplateEngine {
369
-
370
- renderTemplateSource(templateSource: Object, bindingContext?: KnockoutBindingContext, options?: Object): any[];
371
- }
372
-
373
- //////////////////////////////////
374
- // templateEngine.js
375
- //////////////////////////////////
376
-
377
- interface KnockoutTemplateEngine extends KnockoutNativeTemplateEngine {
378
-
379
- createJavaScriptEvaluatorBlock(script: string): string;
380
-
381
- makeTemplateSource(template: any, templateDocument?: Document): any;
382
-
383
- renderTemplate(template: any, bindingContext: KnockoutBindingContext, options: Object, templateDocument: Document): any;
384
-
385
- isTemplateRewritten(template: any, templateDocument: Document): boolean;
386
-
387
- rewriteTemplate(template: any, rewriterCallback: Function, templateDocument: Document): void;
388
- }
389
-
390
- /////////////////////////////////
391
-
392
- interface KnockoutStatic {
393
- utils: KnockoutUtils;
394
- memoization: KnockoutMemoization;
395
-
396
- bindingHandlers: KnockoutBindingHandlers;
397
- getBindingHandler(handler: string): KnockoutBindingHandler;
398
-
399
- virtualElements: KnockoutVirtualElements;
400
- extenders: KnockoutExtenders;
401
-
402
- applyBindings(viewModelOrBindingContext?: any, rootNode?: any): void;
403
- applyBindingsToDescendants(viewModelOrBindingContext: any, rootNode: any): void;
404
- applyBindingAccessorsToNode(node: Node, bindings: (bindingContext: KnockoutBindingContext, node: Node) => {}, bindingContext: KnockoutBindingContext): void;
405
- applyBindingAccessorsToNode(node: Node, bindings: {}, bindingContext: KnockoutBindingContext): void;
406
- applyBindingAccessorsToNode(node: Node, bindings: (bindingContext: KnockoutBindingContext, node: Node) => {}, viewModel: any): void;
407
- applyBindingAccessorsToNode(node: Node, bindings: {}, viewModel: any): void;
408
- applyBindingsToNode(node: Node, bindings: any, viewModelOrBindingContext?: any): any;
409
-
410
- subscribable: KnockoutSubscribableStatic;
411
- observable: KnockoutObservableStatic;
412
-
413
- computed: KnockoutComputedStatic;
414
- pureComputed<T>(evaluatorFunction: () => T, context?: any): KnockoutComputed<T>;
415
- pureComputed<T>(options: KnockoutComputedDefine<T>, context?: any): KnockoutComputed<T>;
416
-
417
- observableArray: KnockoutObservableArrayStatic;
418
-
419
- contextFor(node: any): any;
420
- isSubscribable(instance: any): boolean;
421
- toJSON(viewModel: any, replacer?: Function, space?: any): string;
422
- toJS(viewModel: any): any;
423
- isObservable(instance: any): boolean;
424
- isWriteableObservable(instance: any): boolean;
425
- isComputed(instance: any): boolean;
426
- dataFor(node: any): any;
427
- removeNode(node: Element): void;
428
- cleanNode(node: Element): Element;
429
- renderTemplate(template: Function, viewModel: any, options?: any, target?: any, renderMode?: any): any;
430
- renderTemplate(template: string, viewModel: any, options?: any, target?: any, renderMode?: any): any;
431
- unwrap<T>(value: KnockoutObservable<T> | T): T;
432
-
433
- computedContext: KnockoutComputedContext;
434
-
435
- //////////////////////////////////
436
- // templateSources.js
437
- //////////////////////////////////
438
-
439
- templateSources: KnockoutTemplateSources;
440
-
441
- //////////////////////////////////
442
- // templateEngine.js
443
- //////////////////////////////////
444
-
445
- templateEngine: {
446
-
447
- prototype: KnockoutTemplateEngine;
448
-
449
- new (): KnockoutTemplateEngine;
450
- };
451
-
452
- //////////////////////////////////
453
- // templateRewriting.js
454
- //////////////////////////////////
455
-
456
- templateRewriting: {
457
-
458
- ensureTemplateIsRewritten(template: Node, templateEngine: KnockoutTemplateEngine, templateDocument: Document): any;
459
- ensureTemplateIsRewritten(template: string, templateEngine: KnockoutTemplateEngine, templateDocument: Document): any;
460
-
461
- memoizeBindingAttributeSyntax(htmlString: string, templateEngine: KnockoutTemplateEngine): any;
462
-
463
- applyMemoizedBindingsToNextSibling(bindings: any, nodeName: string): string;
464
- };
465
-
466
- //////////////////////////////////
467
- // nativeTemplateEngine.js
468
- //////////////////////////////////
469
-
470
- nativeTemplateEngine: {
471
-
472
- prototype: KnockoutNativeTemplateEngine;
473
-
474
- new (): KnockoutNativeTemplateEngine;
475
-
476
- instance: KnockoutNativeTemplateEngine;
477
- };
478
-
479
- //////////////////////////////////
480
- // jqueryTmplTemplateEngine.js
481
- //////////////////////////////////
482
-
483
- jqueryTmplTemplateEngine: {
484
-
485
- prototype: KnockoutTemplateEngine;
486
-
487
- renderTemplateSource(templateSource: Object, bindingContext: KnockoutBindingContext, options: Object): Node[];
488
-
489
- createJavaScriptEvaluatorBlock(script: string): string;
490
-
491
- addTemplate(templateName: string, templateMarkup: string): void;
492
- };
493
-
494
- //////////////////////////////////
495
- // templating.js
496
- //////////////////////////////////
497
-
498
- setTemplateEngine(templateEngine: KnockoutNativeTemplateEngine): void;
499
-
500
- renderTemplate(template: Function, dataOrBindingContext: KnockoutBindingContext, options: Object, targetNodeOrNodeArray: Node, renderMode: string): any;
501
- renderTemplate(template: any, dataOrBindingContext: KnockoutBindingContext, options: Object, targetNodeOrNodeArray: Node, renderMode: string): any;
502
- renderTemplate(template: Function, dataOrBindingContext: any, options: Object, targetNodeOrNodeArray: Node, renderMode: string): any;
503
- renderTemplate(template: any, dataOrBindingContext: any, options: Object, targetNodeOrNodeArray: Node, renderMode: string): any;
504
- renderTemplate(template: Function, dataOrBindingContext: KnockoutBindingContext, options: Object, targetNodeOrNodeArray: Node[], renderMode: string): any;
505
- renderTemplate(template: any, dataOrBindingContext: KnockoutBindingContext, options: Object, targetNodeOrNodeArray: Node[], renderMode: string): any;
506
- renderTemplate(template: Function, dataOrBindingContext: any, options: Object, targetNodeOrNodeArray: Node[], renderMode: string): any;
507
- renderTemplate(template: any, dataOrBindingContext: any, options: Object, targetNodeOrNodeArray: Node[], renderMode: string): any;
508
-
509
- renderTemplateForEach(template: Function, arrayOrObservableArray: any[], options: Object, targetNode: Node, parentBindingContext: KnockoutBindingContext): any;
510
- renderTemplateForEach(template: any, arrayOrObservableArray: any[], options: Object, targetNode: Node, parentBindingContext: KnockoutBindingContext): any;
511
- renderTemplateForEach(template: Function, arrayOrObservableArray: KnockoutObservable<any>, options: Object, targetNode: Node, parentBindingContext: KnockoutBindingContext): any;
512
- renderTemplateForEach(template: any, arrayOrObservableArray: KnockoutObservable<any>, options: Object, targetNode: Node, parentBindingContext: KnockoutBindingContext): any;
513
-
514
- expressionRewriting: {
515
- bindingRewriteValidators: any;
516
- parseObjectLiteral: { (objectLiteralString: string): any[] }
517
- };
518
-
519
- /////////////////////////////////
520
-
521
- bindingProvider: {
522
- instance: KnockoutBindingProvider;
523
- new (): KnockoutBindingProvider;
524
- }
525
-
526
- /////////////////////////////////
527
- // selectExtensions.js
528
- /////////////////////////////////
529
-
530
- selectExtensions: {
531
-
532
- readValue(element: HTMLElement): any;
533
-
534
- writeValue(element: HTMLElement, value: any): void;
535
- };
536
-
537
- components: KnockoutComponents;
538
- }
539
-
540
- interface KnockoutBindingProvider {
541
- nodeHasBindings(node: Node): boolean;
542
- getBindings(node: Node, bindingContext: KnockoutBindingContext): {};
543
- getBindingAccessors?(node: Node, bindingContext: KnockoutBindingContext): { [key: string]: string; };
544
- }
545
-
546
- interface KnockoutComputedContext {
547
- getDependenciesCount(): number;
548
- isInitial: () => boolean;
549
- isSleeping: boolean;
550
- }
551
-
552
- //
553
- // refactored types into a namespace to reduce global pollution
554
- // and used Union Types to simplify overloads (requires TypeScript 1.4)
555
- //
556
- declare module KnockoutComponentTypes {
557
-
558
- interface Config {
559
- viewModel?: ViewModelFunction | ViewModelSharedInstance | ViewModelFactoryFunction | AMDModule;
560
- template: string | Node[]| DocumentFragment | TemplateElement | AMDModule;
561
- synchronous?: boolean;
562
- }
563
-
564
- interface ComponentConfig {
565
- viewModel?: ViewModelFunction | ViewModelSharedInstance | ViewModelFactoryFunction | AMDModule;
566
- template: any;
567
- createViewModel?: any;
568
- }
569
-
570
- interface EmptyConfig {
571
- }
572
-
573
- // common AMD type
574
- interface AMDModule {
575
- require: string;
576
- }
577
-
578
- // viewmodel types
579
- interface ViewModelFunction {
580
- (params?: any): any;
581
- }
582
-
583
- interface ViewModelSharedInstance {
584
- instance: any;
585
- }
586
-
587
- interface ViewModelFactoryFunction {
588
- createViewModel: (params?: any, componentInfo?: ComponentInfo) => any;
589
- }
590
-
591
- interface ComponentInfo {
592
- element: Node;
593
- templateNodes: Node[];
594
- }
595
-
596
- interface TemplateElement {
597
- element: string | Node;
598
- }
599
-
600
- interface Loader {
601
- getConfig? (componentName: string, callback: (result: ComponentConfig) => void): void;
602
- loadComponent? (componentName: string, config: ComponentConfig, callback: (result: Definition) => void): void;
603
- loadTemplate? (componentName: string, templateConfig: any, callback: (result: Node[]) => void): void;
604
- loadViewModel? (componentName: string, viewModelConfig: any, callback: (result: any) => void): void;
605
- suppressLoaderExceptions?: boolean;
606
- }
607
-
608
- interface Definition {
609
- template: Node[];
610
- createViewModel? (params: any, options: { element: Node; }): any;
611
- }
612
- }
613
-
614
- interface KnockoutComponents {
615
- // overloads for register method:
616
- register(componentName: string, config: KnockoutComponentTypes.Config | KnockoutComponentTypes.EmptyConfig): void;
617
-
618
- isRegistered(componentName: string): boolean;
619
- unregister(componentName: string): void;
620
- get(componentName: string, callback: (definition: KnockoutComponentTypes.Definition) => void): void;
621
- clearCachedDefinition(componentName: string): void
622
- defaultLoader: KnockoutComponentTypes.Loader;
623
- loaders: KnockoutComponentTypes.Loader[];
624
- getComponentNameForNode(node: Node): string;
625
- }
626
-
627
- declare var ko: KnockoutStatic;
628
-
629
- declare module "knockout" {
630
- export = ko;
631
- }
1
+ // Type definitions for Knockout v3.4.0
2
+ // Project: http://knockoutjs.com
3
+ // Definitions by: Boris Yankov <https://github.com/borisyankov>,
4
+ // Igor Oleinikov <https://github.com/Igorbek>,
5
+ // Clément Bourgeois <https://github.com/moonpyk>,
6
+ // Matt Brooks <https://github.com/EnableSoftware>,
7
+ // Benjamin Eckardt <https://github.com/BenjaminEckardt>,
8
+ // Mathias Lorenzen <https://github.com/ffMathy>,
9
+ // Leonardo Lombardi <https://github.com/ltlombardi>
10
+ // Retsam <https://github.com/Retsam>
11
+ // Definitions: https://github.com/DefinitelyTyped/DefinitelyTyped
12
+ // TypeScript Version: 2.3
13
+
14
+ interface KnockoutSubscribableFunctions<T> {
15
+ /**
16
+ * Notify subscribers of knockout "change" event. This doesn't actually change the observable value.
17
+ * @param eventValue A value to be sent with the event.
18
+ * @param event The knockout event.
19
+ */
20
+ notifySubscribers(eventValue?: T, event?: "change"): void;
21
+ /**
22
+ * Notify subscribers of a knockout or user defined event.
23
+ * @param eventValue A value to be sent with the event.
24
+ * @param event The knockout or user defined event name.
25
+ */
26
+ notifySubscribers<U>(eventValue: U, event: string): void;
27
+ }
28
+
29
+ interface KnockoutComputedFunctions<T> {
30
+ }
31
+
32
+ interface KnockoutObservableFunctions<T> {
33
+ /**
34
+ * Used by knockout to decide if value of observable has changed and should notify subscribers. Returns true if instances are primitives, and false if are objects.
35
+ * If your observable holds an object, this can be overwritten to return equality based on your needs.
36
+ * @param a previous value.
37
+ * @param b next value.
38
+ */
39
+ equalityComparer(a: T, b: T): boolean;
40
+ }
41
+
42
+ // The functions of observable arrays that don't mutate the array
43
+ interface KnockoutReadonlyObservableArrayFunctions<T> {
44
+ /**
45
+ * Returns the index of the first occurrence of a value in an array.
46
+ * @param searchElement The value to locate in the array.
47
+ * @param fromIndex The array index at which to begin the search. If fromIndex is omitted, the search starts at index 0.
48
+ */
49
+ indexOf(searchElement: T, fromIndex?: number): number;
50
+ /**
51
+ * Returns a section of an array.
52
+ * @param start The beginning of the specified portion of the array.
53
+ * @param end The end of the specified portion of the array.
54
+ */
55
+ slice(start: number, end?: number): T[];
56
+ }
57
+ // The functions of observable arrays that mutate the array
58
+ interface KnockoutObservableArrayFunctions<T> extends KnockoutReadonlyObservableArrayFunctions<T> {
59
+ /**
60
+ * Removes and returns all the remaining elements starting from a given index.
61
+ * @param start The zero-based location in the array from which to start removing elements.
62
+ */
63
+ splice(start: number): T[];
64
+ /**
65
+ * Removes elements from an array and, if necessary, inserts new elements in their place, returning the deleted elements.
66
+ * @param start The zero-based location in the array from which to start removing elements.
67
+ * @param deleteCount The number of elements to remove.
68
+ * @param items Elements to insert into the array in place of the deleted elements.
69
+ */
70
+ splice(start: number, deleteCount: number, ...items: T[]): T[];
71
+ /**
72
+ * Removes the last value from the array and returns it.
73
+ */
74
+ pop(): T;
75
+ /**
76
+ * Adds new item or items to the end of array.
77
+ * @param items Items to be added.
78
+ */
79
+ push(...items: T[]): void;
80
+ /**
81
+ * Removes the first value from the array and returns it.
82
+ */
83
+ shift(): T;
84
+ /**
85
+ * Inserts new item or items at the beginning of the array.
86
+ * @param items Items to be added.
87
+ */
88
+ unshift(...items: T[]): number;
89
+ /**
90
+ * Reverses the order of the array and returns the observableArray (not the underlying array).
91
+ */
92
+ reverse(): KnockoutObservableArray<T>;
93
+ /**
94
+ * Sorts the array contents and returns the observableArray.
95
+ */
96
+ sort(): KnockoutObservableArray<T>;
97
+ /**
98
+ * Sorts the array contents and returns the observableArray.
99
+ * @param compareFunction A function that returns negative value if first argument is smaller, positive value if second is smaller, or zero to treat them as equal.
100
+ */
101
+ sort(compareFunction: (left: T, right: T) => number): KnockoutObservableArray<T>;
102
+
103
+ // Ko specific
104
+ /**
105
+ * Replaces the first value that equals oldItem with newItem.
106
+ * @param oldItem Item to be replaced.
107
+ * @param newItem Replacing item.
108
+ */
109
+ replace(oldItem: T, newItem: T): void;
110
+ /**
111
+ * Removes all values that equal item and returns them as an array.
112
+ * @param item The item to be removed.
113
+ */
114
+ remove(item: T): T[];
115
+ /**
116
+ * Removes all values and returns them as an array.
117
+ * @param removeFunction A function used to determine true if item should be removed and fasle otherwise.
118
+ */
119
+ remove(removeFunction: (item: T) => boolean): T[];
120
+ /**
121
+ * Removes all values that equal any of the supplied items.
122
+ * @param items Items to be removed.
123
+ */
124
+ removeAll(items: T[]): T[];
125
+ /**
126
+ * Removes all values and returns them as an array.
127
+ */
128
+ removeAll(): T[];
129
+
130
+ // Ko specific Usually relevant to Ruby on Rails developers only
131
+ /**
132
+ * Finds any objects in the array that equal someItem and gives them a special property called _destroy with value true.
133
+ * @param item Items to be marked with the property.
134
+ */
135
+ destroy(item: T): void;
136
+ /**
137
+ * Finds any objects in the array filtered by a function and gives them a special property called _destroy with value true.
138
+ * @param destroyFunction A function used to determine which items should be marked with the property.
139
+ */
140
+ destroy(destroyFunction: (item: T) => boolean): void;
141
+ /**
142
+ * Finds any objects in the array that equal suplied items and gives them a special property called _destroy with value true.
143
+ * @param items
144
+ */
145
+ destroyAll(items: T[]): void;
146
+ /**
147
+ * Gives a special property called _destroy with value true to all objects in the array.
148
+ */
149
+ destroyAll(): void;
150
+ }
151
+
152
+ interface KnockoutSubscribableStatic {
153
+ fn: KnockoutSubscribableFunctions<any>;
154
+
155
+ new <T>(): KnockoutSubscribable<T>;
156
+ }
157
+
158
+ interface KnockoutSubscription {
159
+ /**
160
+ * Terminates a subscription.
161
+ */
162
+ dispose(): void;
163
+ }
164
+
165
+ interface KnockoutSubscribable<T> extends KnockoutSubscribableFunctions<T> {
166
+ /**
167
+ * Registers to be notified after the observable's value changes.
168
+ * @param callback Function that is called whenever the notification happens.
169
+ * @param target Defines the value of 'this' in the callback function.
170
+ * @param event The knockout event name.
171
+ */
172
+ subscribe(callback: (newValue: T) => void, target?: any, event?: "change"): KnockoutSubscription;
173
+ /**
174
+ * Registers to be notified before the observable's value changes.
175
+ * @param callback Function that is called whenever the notification happens.
176
+ * @param target Defines the value of 'this' in the callback function.
177
+ * @param event The knockout event name.
178
+ */
179
+ subscribe(callback: (newValue: T) => void, target: any, event: "beforeChange"): KnockoutSubscription;
180
+ /**
181
+ * Registers to be notified when a knockout or user defined event happens.
182
+ * @param callback Function that is called whenever the notification happens. eventValue can be anything. No relation to underlying observable.
183
+ * @param target Defines the value of 'this' in the callback function.
184
+ * @param event The knockout or user defined event name.
185
+ */
186
+ subscribe<U>(callback: (eventValue: U) => void, target: any, event: string): KnockoutSubscription;
187
+ /**
188
+ * Customizes observables basic functionality.
189
+ * @param requestedExtenders Name of the extender feature and its value, e.g. { notify: 'always' }, { rateLimit: 50 }
190
+ */
191
+ extend(requestedExtenders: { [key: string]: any; }): KnockoutSubscribable<T>;
192
+ /**
193
+ * Gets total number of subscribers.
194
+ */
195
+ getSubscriptionsCount(): number;
196
+ /**
197
+ * Gets number of subscribers of a particular event.
198
+ * @param event Event name.
199
+ */
200
+ getSubscriptionsCount(event: string): number;
201
+ }
202
+
203
+ interface KnockoutComputedStatic {
204
+ fn: KnockoutComputedFunctions<any>;
205
+
206
+ /**
207
+ * Creates computed observable.
208
+ */
209
+ <T>(): KnockoutComputed<T>;
210
+ /**
211
+ * Creates computed observable.
212
+ * @param evaluatorFunction Function that computes the observable value.
213
+ * @param context Defines the value of 'this' when evaluating the computed observable.
214
+ * @param options An object with further properties for the computed observable.
215
+ */
216
+ <T>(evaluatorFunction: () => T, context?: any, options?: KnockoutComputedOptions<T>): KnockoutComputed<T>;
217
+ /**
218
+ * Creates computed observable.
219
+ * @param options An object that defines the computed observable options and behavior.
220
+ * @param context Defines the value of 'this' when evaluating the computed observable.
221
+ */
222
+ <T>(options: KnockoutComputedDefine<T>, context?: any): KnockoutComputed<T>;
223
+ }
224
+
225
+ interface KnockoutReadonlyComputed<T> extends KnockoutReadonlyObservable<T> {
226
+ /**
227
+ * Returns whether the computed observable may be updated in the future. A computed observable is inactive if it has no dependencies.
228
+ */
229
+ isActive(): boolean;
230
+ /**
231
+ * Returns the current number of dependencies of the computed observable.
232
+ */
233
+ getDependenciesCount(): number;
234
+ }
235
+
236
+ interface KnockoutComputed<T> extends KnockoutReadonlyComputed<T>, KnockoutObservable<T>, KnockoutComputedFunctions<T> {
237
+ fn: KnockoutComputedFunctions<any>;
238
+
239
+ /**
240
+ * Manually disposes the computed observable, clearing all subscriptions to dependencies.
241
+ * This function is useful if you want to stop a computed observable from being updated or want to clean up memory for a
242
+ * computed observable that has dependencies on observables that won’t be cleaned.
243
+ */
244
+ dispose(): void;
245
+ /**
246
+ * Customizes observables basic functionality.
247
+ * @param requestedExtenders Name of the extender feature and it's value, e.g. { notify: 'always' }, { rateLimit: 50 }
248
+ */
249
+ extend(requestedExtenders: { [key: string]: any; }): KnockoutComputed<T>;
250
+ }
251
+
252
+ interface KnockoutObservableArrayStatic {
253
+ fn: KnockoutObservableArrayFunctions<any>;
254
+
255
+ <T>(value?: T[] | null): KnockoutObservableArray<T>;
256
+ }
257
+
258
+ /**
259
+ * While all observable arrays are writable at runtime, this type is analogous to the native ReadonlyArray type:
260
+ * casting an observable array to this type expresses the intention that it shouldn't be mutated.
261
+ */
262
+ interface KnockoutReadonlyObservableArray<T> extends KnockoutReadonlyObservable<ReadonlyArray<T>>, KnockoutReadonlyObservableArrayFunctions<T> {
263
+ // NOTE: Keep in sync with KnockoutObservableArray<T>, see note on KnockoutObservableArray<T>
264
+ subscribe(callback: (newValue: KnockoutArrayChange<T>[]) => void, target: any, event: "arrayChange"): KnockoutSubscription;
265
+ subscribe(callback: (newValue: T[]) => void, target: any, event: "beforeChange"): KnockoutSubscription;
266
+ subscribe(callback: (newValue: T[]) => void, target?: any, event?: "change"): KnockoutSubscription;
267
+ subscribe<U>(callback: (newValue: U) => void, target: any, event: string): KnockoutSubscription;
268
+ }
269
+
270
+ /*
271
+ NOTE: In theory this should extend both KnockoutObservable<T[]> and KnockoutReadonlyObservableArray<T>,
272
+ but can't since they both provide conflicting typings of .subscribe.
273
+ So it extends KnockoutObservable<T[]> and duplicates the subscribe definitions, which should be kept in sync
274
+ */
275
+ interface KnockoutObservableArray<T> extends KnockoutObservable<T[]>, KnockoutObservableArrayFunctions<T> {
276
+ subscribe(callback: (newValue: KnockoutArrayChange<T>[]) => void, target: any, event: "arrayChange"): KnockoutSubscription;
277
+ subscribe(callback: (newValue: T[]) => void, target: any, event: "beforeChange"): KnockoutSubscription;
278
+ subscribe(callback: (newValue: T[]) => void, target?: any, event?: "change"): KnockoutSubscription;
279
+ subscribe<U>(callback: (newValue: U) => void, target: any, event: string): KnockoutSubscription;
280
+
281
+ extend(requestedExtenders: { [key: string]: any; }): KnockoutObservableArray<T>;
282
+ }
283
+
284
+ interface KnockoutObservableStatic {
285
+ fn: KnockoutObservableFunctions<any>;
286
+
287
+ <T>(value: T): KnockoutObservable<T>;
288
+ <T = any>(value: null): KnockoutObservable<T | null>
289
+ <T = any>(): KnockoutObservable<T | undefined>
290
+ }
291
+
292
+ /**
293
+ * While all observable are writable at runtime, this type is analogous to the native ReadonlyArray type:
294
+ * casting an observable to this type expresses the intention that this observable shouldn't be mutated.
295
+ */
296
+ interface KnockoutReadonlyObservable<T> extends KnockoutSubscribable<T>, KnockoutObservableFunctions<T> {
297
+ (): T;
298
+
299
+ /**
300
+ * Returns the current value of the computed observable without creating a dependency.
301
+ */
302
+ peek(): T;
303
+ valueHasMutated?: { (): void; };
304
+ valueWillMutate?: { (): void; };
305
+ }
306
+
307
+ interface KnockoutObservable<T> extends KnockoutReadonlyObservable<T> {
308
+ (value: T): void;
309
+
310
+ // Since .extend does arbitrary thing to an observable, it's not safe to do on a readonly observable
311
+ /**
312
+ * Customizes observables basic functionality.
313
+ * @param requestedExtenders Name of the extender feature and it's value, e.g. { notify: 'always' }, { rateLimit: 50 }
314
+ */
315
+ extend(requestedExtenders: { [key: string]: any; }): KnockoutObservable<T>;
316
+ }
317
+
318
+ interface KnockoutComputedOptions<T> {
319
+ /**
320
+ * Makes the computed observable writable. This is a function that receives values that other code is trying to write to your computed observable.
321
+ * It’s up to you to supply custom logic to handle the incoming values, typically by writing the values to some underlying observable(s).
322
+ * @param value Value being written to the computer observable.
323
+ */
324
+ write?(value: T): void;
325
+ /**
326
+ * Disposal of the computed observable will be triggered when the specified DOM node is removed by KO.
327
+ * This feature is used to dispose computed observables used in bindings when nodes are removed by the template and control-flow bindings.
328
+ */
329
+ disposeWhenNodeIsRemoved?: Node;
330
+ /**
331
+ * This function is executed before each re-evaluation to determine if the computed observable should be disposed.
332
+ * A true-ish result will trigger disposal of the computed observable.
333
+ */
334
+ disposeWhen?(): boolean;
335
+ /**
336
+ * Defines the value of 'this' whenever KO invokes your 'read' or 'write' callbacks.
337
+ */
338
+ owner?: any;
339
+ /**
340
+ * If true, then the value of the computed observable will not be evaluated until something actually attempts to access its value or manually subscribes to it.
341
+ * By default, a computed observable has its value determined immediately during creation.
342
+ */
343
+ deferEvaluation?: boolean;
344
+ /**
345
+ * If true, the computed observable will be set up as a purecomputed observable. This option is an alternative to the ko.pureComputed constructor.
346
+ */
347
+ pure?: boolean;
348
+ }
349
+
350
+ interface KnockoutComputedDefine<T> extends KnockoutComputedOptions<T> {
351
+ /**
352
+ * A function that is used to evaluate the computed observable’s current value.
353
+ */
354
+ read(): T;
355
+ }
356
+
357
+ interface KnockoutBindingContext {
358
+ $parent: any;
359
+ $parents: any[];
360
+ $root: any;
361
+ $data: any;
362
+ $rawData: any | KnockoutObservable<any>;
363
+ $index?: KnockoutObservable<number>;
364
+ $parentContext?: KnockoutBindingContext;
365
+ $component: any;
366
+ $componentTemplateNodes: Node[];
367
+
368
+ /**
369
+ * Clones the current Binding Context, adding extra properties to it.
370
+ * @param properties object with properties to be added in the binding context.
371
+ */
372
+ extend(properties: { [key: string]: any; } | (() => { [key: string]: any; })): KnockoutBindingContext;
373
+ /**
374
+ * This returns a new binding context whose viewmodel is the first parameter and whose $parentContext is the current bindingContext.
375
+ * @param dataItemOrAccessor The binding context of the children.
376
+ * @param dataItemAlias An alias for the data item in descendant contexts.
377
+ * @param extendCallback Function to be called.
378
+ * @param options Further options.
379
+ */
380
+ createChildContext(dataItemOrAccessor: any, dataItemAlias?: string, extendCallback?: Function, options?: { "exportDependencies": boolean }): any;
381
+ }
382
+
383
+ interface KnockoutAllBindingsAccessor {
384
+ (): any;
385
+ get(name: string): any;
386
+ has(name: string): boolean;
387
+ }
388
+
389
+ interface KnockoutBindingHandler<E extends Node = any, V = any, VM = any> {
390
+ after?: Array<string>;
391
+ init?: (element: E, valueAccessor: () => V, allBindingsAccessor: KnockoutAllBindingsAccessor, viewModel: VM, bindingContext: KnockoutBindingContext) => void | { controlsDescendantBindings: boolean; };
392
+ update?: (element: E, valueAccessor: () => V, allBindingsAccessor: KnockoutAllBindingsAccessor, viewModel: VM, bindingContext: KnockoutBindingContext) => void;
393
+ options?: any;
394
+ preprocess?: (value: string, name: string, addBindingCallback?: (name: string, value: string) => void) => string;
395
+ [s: string]: any;
396
+ }
397
+
398
+ interface KnockoutBindingHandlers {
399
+ [bindingHandler: string]: KnockoutBindingHandler;
400
+
401
+ // Controlling text and appearance
402
+ visible: KnockoutBindingHandler;
403
+ text: KnockoutBindingHandler;
404
+ html: KnockoutBindingHandler;
405
+ css: KnockoutBindingHandler;
406
+ style: KnockoutBindingHandler;
407
+ attr: KnockoutBindingHandler;
408
+
409
+ // Control Flow
410
+ foreach: KnockoutBindingHandler;
411
+ if: KnockoutBindingHandler;
412
+ ifnot: KnockoutBindingHandler;
413
+ with: KnockoutBindingHandler;
414
+
415
+ // Working with form fields
416
+ click: KnockoutBindingHandler;
417
+ event: KnockoutBindingHandler;
418
+ submit: KnockoutBindingHandler;
419
+ enable: KnockoutBindingHandler;
420
+ disable: KnockoutBindingHandler;
421
+ value: KnockoutBindingHandler;
422
+ textInput: KnockoutBindingHandler;
423
+ hasfocus: KnockoutBindingHandler;
424
+ checked: KnockoutBindingHandler;
425
+ options: KnockoutBindingHandler;
426
+ selectedOptions: KnockoutBindingHandler;
427
+ uniqueName: KnockoutBindingHandler;
428
+
429
+ // Rendering templates
430
+ template: KnockoutBindingHandler;
431
+
432
+ // Components (new for v3.2)
433
+ component: KnockoutBindingHandler;
434
+ }
435
+
436
+ interface KnockoutMemoization {
437
+ memoize(callback: Function): string;
438
+ unmemoize(memoId: string, callbackParams: any[]): boolean;
439
+ unmemoizeDomNodeAndDescendants(domNode: any, extraCallbackParamsArray: any[]): boolean;
440
+ parseMemoText(memoText: string): string;
441
+ }
442
+
443
+ interface KnockoutVirtualElement { }
444
+
445
+ interface KnockoutVirtualElements {
446
+ allowedBindings: { [bindingName: string]: boolean; };
447
+ emptyNode(node: KnockoutVirtualElement): void;
448
+ firstChild(node: KnockoutVirtualElement): KnockoutVirtualElement;
449
+ insertAfter(container: KnockoutVirtualElement, nodeToInsert: Node, insertAfter: Node): void;
450
+ nextSibling(node: KnockoutVirtualElement): Node;
451
+ prepend(node: KnockoutVirtualElement, toInsert: Node): void;
452
+ setDomNodeChildren(node: KnockoutVirtualElement, newChildren: { length: number;[index: number]: Node; }): void;
453
+ childNodes(node: KnockoutVirtualElement): Node[];
454
+ }
455
+
456
+ interface KnockoutExtenders {
457
+ throttle(target: any, timeout: number): KnockoutComputed<any>;
458
+ notify(target: any, notifyWhen: string): any;
459
+
460
+ rateLimit(target: any, timeout: number): any;
461
+ rateLimit(target: any, options: { timeout: number; method?: string; }): any;
462
+
463
+ trackArrayChanges(target: any): any;
464
+ }
465
+
466
+ //
467
+ // NOTE TO MAINTAINERS AND CONTRIBUTORS : pay attention to only include symbols that are
468
+ // publicly exported in the minified version of ko, without that you can give the false
469
+ // impression that some functions will be available in production builds.
470
+ //
471
+ interface KnockoutUtils {
472
+ //////////////////////////////////
473
+ // utils.domData.js
474
+ //////////////////////////////////
475
+
476
+ domData: {
477
+ get(node: Node, key: string): any;
478
+
479
+ set(node: Node, key: string, value: any): void;
480
+
481
+ getAll(node: Node, createIfNotFound: boolean): any;
482
+
483
+ clear(node: Node): boolean;
484
+ };
485
+
486
+ //////////////////////////////////
487
+ // utils.domNodeDisposal.js
488
+ //////////////////////////////////
489
+
490
+ domNodeDisposal: {
491
+ addDisposeCallback(node: Node, callback: Function): void;
492
+
493
+ removeDisposeCallback(node: Node, callback: Function): void;
494
+
495
+ cleanNode(node: Node): Node;
496
+
497
+ removeNode(node: Node): void;
498
+ };
499
+
500
+ addOrRemoveItem<T>(array: T[] | KnockoutObservable<T>, value: T, included: T): void;
501
+
502
+ arrayFilter<T>(array: T[], predicate: (item: T) => boolean): T[];
503
+
504
+ arrayFirst<T>(array: T[], predicate: (item: T) => boolean, predicateOwner?: any): T;
505
+
506
+ arrayForEach<T>(array: T[], action: (item: T, index: number) => void): void;
507
+
508
+ arrayGetDistinctValues<T>(array: T[]): T[];
509
+
510
+ arrayIndexOf<T>(array: T[], item: T): number;
511
+
512
+ arrayMap<T, U>(array: T[], mapping: (item: T) => U): U[];
513
+
514
+ arrayPushAll<T>(array: T[] | KnockoutObservableArray<T>, valuesToPush: T[]): T[];
515
+
516
+ arrayRemoveItem(array: any[], itemToRemove: any): void;
517
+
518
+ compareArrays<T>(a: T[], b: T[]): Array<KnockoutArrayChange<T>>;
519
+
520
+ extend(target: Object, source: Object): Object;
521
+
522
+ fieldsIncludedWithJsonPost: any[];
523
+
524
+ getFormFields(form: any, fieldName: string): any[];
525
+
526
+ objectForEach(obj: any, action: (key: any, value: any) => void): void;
527
+
528
+ parseHtmlFragment(html: string): any[];
529
+
530
+ parseJson(jsonString: string): any;
531
+
532
+ postJson(urlOrForm: any, data: any, options: any): void;
533
+
534
+ peekObservable<T>(value: KnockoutObservable<T>): T;
535
+
536
+ range(min: any, max: any): any;
537
+
538
+ registerEventHandler(element: any, eventType: any, handler: Function): void;
539
+
540
+ setHtml(node: Element, html: () => string): void;
541
+
542
+ setHtml(node: Element, html: string): void;
543
+
544
+ setTextContent(element: any, textContent: string | KnockoutObservable<string>): void;
545
+
546
+ stringifyJson(data: any, replacer?: Function, space?: string): string;
547
+
548
+ toggleDomNodeCssClass(node: any, className: string, shouldHaveClass: boolean): void;
549
+
550
+ triggerEvent(element: any, eventType: any): void;
551
+
552
+ unwrapObservable<T>(value: KnockoutObservable<T> | T): T;
553
+ unwrapObservable<T>(value: KnockoutObservableArray<T> | T[]): T[];
554
+
555
+ // NOT PART OF THE MINIFIED API SURFACE (ONLY IN knockout-{version}.debug.js) https://github.com/SteveSanderson/knockout/issues/670
556
+ // forceRefresh(node: any): void;
557
+ // ieVersion: number;
558
+ // isIe6: boolean;
559
+ // isIe7: boolean;
560
+ // jQueryHtmlParse(html: string): any[];
561
+ // makeArray(arrayLikeObject: any): any[];
562
+ // moveCleanedNodesToContainerElement(nodes: any[]): HTMLElement;
563
+ // replaceDomNodes(nodeToReplaceOrNodeArray: any, newNodesArray: any[]): void;
564
+ // setDomNodeChildren(domNode: any, childNodes: any[]): void;
565
+ // setElementName(element: any, name: string): void;
566
+ // setOptionNodeSelectionState(optionNode: any, isSelected: boolean): void;
567
+ // simpleHtmlParse(html: string): any[];
568
+ // stringStartsWith(str: string, startsWith: string): boolean;
569
+ // stringTokenize(str: string, delimiter: string): string[];
570
+ // stringTrim(str: string): string;
571
+ // tagNameLower(element: any): string;
572
+ }
573
+
574
+ interface KnockoutArrayChange<T> {
575
+ status: "added" | "deleted" | "retained";
576
+ value: T;
577
+ index: number;
578
+ moved?: number;
579
+ }
580
+
581
+ //////////////////////////////////
582
+ // templateSources.js
583
+ //////////////////////////////////
584
+
585
+ interface KnockoutTemplateSourcesDomElement {
586
+ text(): any;
587
+ text(value: any): void;
588
+
589
+ data(key: string): any;
590
+ data(key: string, value: any): any;
591
+ }
592
+
593
+ interface KnockoutTemplateAnonymous extends KnockoutTemplateSourcesDomElement {
594
+ nodes(): any;
595
+ nodes(value: any): void;
596
+ }
597
+
598
+ interface KnockoutTemplateSources {
599
+
600
+ domElement: {
601
+ prototype: KnockoutTemplateSourcesDomElement
602
+ new(element: Element): KnockoutTemplateSourcesDomElement
603
+ };
604
+
605
+ anonymousTemplate: {
606
+ prototype: KnockoutTemplateAnonymous;
607
+ new(element: Element): KnockoutTemplateAnonymous;
608
+ };
609
+ }
610
+
611
+ //////////////////////////////////
612
+ // nativeTemplateEngine.js
613
+ //////////////////////////////////
614
+
615
+ interface KnockoutNativeTemplateEngine extends KnockoutTemplateEngine {
616
+
617
+ renderTemplateSource(templateSource: Object, bindingContext?: KnockoutBindingContext, options?: Object): any[];
618
+ }
619
+
620
+ //////////////////////////////////
621
+ // templateEngine.js
622
+ //////////////////////////////////
623
+
624
+ interface KnockoutTemplateEngine {
625
+
626
+ createJavaScriptEvaluatorBlock(script: string): string;
627
+
628
+ makeTemplateSource(template: any, templateDocument?: Document): any;
629
+
630
+ renderTemplate(template: any, bindingContext: KnockoutBindingContext, options: Object, templateDocument: Document): any;
631
+
632
+ isTemplateRewritten(template: any, templateDocument: Document): boolean;
633
+
634
+ rewriteTemplate(template: any, rewriterCallback: Function, templateDocument: Document): void;
635
+ }
636
+
637
+ //////////////////////////////////
638
+ // tasks.js
639
+ //////////////////////////////////
640
+
641
+ interface KnockoutTasks {
642
+ scheduler: (callback: Function) => any;
643
+ schedule(task: Function): number;
644
+ cancel(handle: number): void;
645
+ runEarly(): void;
646
+ }
647
+
648
+ /////////////////////////////////
649
+ interface KnockoutStatic {
650
+ utils: KnockoutUtils;
651
+ memoization: KnockoutMemoization;
652
+
653
+ bindingHandlers: KnockoutBindingHandlers;
654
+ getBindingHandler(handler: string): KnockoutBindingHandler;
655
+
656
+ virtualElements: KnockoutVirtualElements;
657
+ extenders: KnockoutExtenders;
658
+
659
+ applyBindings(viewModelOrBindingContext?: any, rootNode?: any): void;
660
+ applyBindingsToDescendants(viewModelOrBindingContext: any, rootNode: any): void;
661
+ applyBindingAccessorsToNode(node: Node, bindings: (bindingContext: KnockoutBindingContext, node: Node) => {}, bindingContext: KnockoutBindingContext): void;
662
+ applyBindingAccessorsToNode(node: Node, bindings: {}, bindingContext: KnockoutBindingContext): void;
663
+ applyBindingAccessorsToNode(node: Node, bindings: (bindingContext: KnockoutBindingContext, node: Node) => {}, viewModel: any): void;
664
+ applyBindingAccessorsToNode(node: Node, bindings: {}, viewModel: any): void;
665
+ applyBindingsToNode(node: Node, bindings: any, viewModelOrBindingContext?: any): any;
666
+
667
+ subscribable: KnockoutSubscribableStatic;
668
+ observable: KnockoutObservableStatic;
669
+
670
+ computed: KnockoutComputedStatic;
671
+ /**
672
+ * Creates a pure computed observable.
673
+ * @param evaluatorFunction Function that computes the observable value.
674
+ * @param context Defines the value of 'this' when evaluating the computed observable.
675
+ */
676
+ pureComputed<T>(evaluatorFunction: () => T, context?: any): KnockoutComputed<T>;
677
+ /**
678
+ * Creates a pure computed observable.
679
+ * @param options An object that defines the computed observable options and behavior.
680
+ * @param context Defines the value of 'this' when evaluating the computed observable.
681
+ */
682
+ pureComputed<T>(options: KnockoutComputedDefine<T>, context?: any): KnockoutComputed<T>;
683
+
684
+ observableArray: KnockoutObservableArrayStatic;
685
+
686
+ /**
687
+ * Evaluates if instance is a KnockoutSubscribable.
688
+ * @param instance Instance to be evaluated.
689
+ */
690
+ isSubscribable(instance: any): instance is KnockoutSubscribable<any>;
691
+ /**
692
+ * Clones object substituting each observable for it's underlying value. Uses browser JSON.stringify internally to stringify the result.
693
+ * @param viewModel Object with observables to be converted.
694
+ * @param replacer A Function or array of names that alters the behavior of the stringification process.
695
+ * @param space Used to insert white space into the output JSON string for readability purposes.
696
+ */
697
+ toJSON(viewModel: any, replacer?: Function | [string | number], space?: string | number): string;
698
+ /**
699
+ * Clones object substituting for each observable the current value of that observable.
700
+ * @param viewModel Object with observables to be converted.
701
+ */
702
+ toJS(viewModel: any): any;
703
+ /**
704
+ * Determine if argument is an observable. Returns true for observables, observable arrays, and all computed observables.
705
+ * @param instance Object to be checked.
706
+ */
707
+ isObservable(instance: any): instance is KnockoutObservable<any>;
708
+ /**
709
+ * Determine if argument is an observable. Returns true for observables, observable arrays, and all computed observables.
710
+ * @param instance Object to be checked.
711
+ */
712
+ isObservable<T>(instance: KnockoutObservable<T> | T): instance is KnockoutObservable<T>;
713
+ /**
714
+ * Determine if argument is a writable observable. Returns true for observables, observable arrays, and writable computed observables.
715
+ * @param instance Object to be checked.
716
+ */
717
+ isWriteableObservable(instance: any): instance is KnockoutObservable<any>;
718
+ /**
719
+ * Determine if argument is a writable observable. Returns true for observables, observable arrays, and writable computed observables.
720
+ * @param instance Object to be checked.
721
+ */
722
+ isWriteableObservable<T>(instance: KnockoutObservable<T> | T): instance is KnockoutObservable<T>;
723
+ /**
724
+ * Determine if argument is a computed observable.
725
+ * @param instance Object to be checked.
726
+ */
727
+ isComputed(instance: any): instance is KnockoutComputed<any>;
728
+ /**
729
+ * Determine if argument is a computed observable.
730
+ * @param instance Object to be checked.
731
+ */
732
+ isComputed<T>(instance: KnockoutObservable<T> | T): instance is KnockoutComputed<T>;
733
+
734
+ /**
735
+ * Returns the data that was available for binding against the element.
736
+ * @param node Html node that contains the binding context.
737
+ */
738
+ dataFor(node: Node): any;
739
+ /**
740
+ * Returns the entire binding context that was available to the DOM element.
741
+ * @param node Html node that contains the binding context.
742
+ */
743
+ contextFor(node: Node): any;
744
+ /**
745
+ * Removes a node from the DOM.
746
+ * @param node Node to be removed.
747
+ */
748
+ removeNode(node: Node): void;
749
+ /**
750
+ * Used internally by Knockout to clean up data/computeds that it created related to the element. It does not remove any event handlers added by bindings.
751
+ * @param node Node to be cleaned.
752
+ */
753
+ cleanNode(node: Node): Node;
754
+ renderTemplate(template: Function, viewModel: any, options?: any, target?: any, renderMode?: any): any;
755
+ renderTemplate(template: string, viewModel: any, options?: any, target?: any, renderMode?: any): any;
756
+ /**
757
+ * Returns the underlying value of the Knockout Observable or in case of plain js object, return the object. Use this to easily accept both observable and plain values.
758
+ * @param instance observable to be unwraped if it's an Observable.
759
+ */
760
+ unwrap<T>(instance: KnockoutObservable<T> | T): T;
761
+ /**
762
+ * Gets the array inside the KnockoutObservableArray.
763
+ * @param instance observable to be unwraped.
764
+ */
765
+ unwrap<T>(instance: KnockoutObservableArray<T> | T[]): T[];
766
+
767
+ /**
768
+ * Get information about the current computed property during the execution of a computed observable’s evaluator function.
769
+ */
770
+ computedContext: KnockoutComputedContext;
771
+
772
+ //////////////////////////////////
773
+ // templateSources.js
774
+ //////////////////////////////////
775
+
776
+ templateSources: KnockoutTemplateSources;
777
+
778
+ //////////////////////////////////
779
+ // templateEngine.js
780
+ //////////////////////////////////
781
+
782
+ templateEngine: {
783
+
784
+ prototype: KnockoutTemplateEngine;
785
+
786
+ new(): KnockoutTemplateEngine;
787
+ };
788
+
789
+ //////////////////////////////////
790
+ // templateRewriting.js
791
+ //////////////////////////////////
792
+
793
+ templateRewriting: {
794
+
795
+ ensureTemplateIsRewritten(template: Node, templateEngine: KnockoutTemplateEngine, templateDocument: Document): any;
796
+ ensureTemplateIsRewritten(template: string, templateEngine: KnockoutTemplateEngine, templateDocument: Document): any;
797
+
798
+ memoizeBindingAttributeSyntax(htmlString: string, templateEngine: KnockoutTemplateEngine): any;
799
+
800
+ applyMemoizedBindingsToNextSibling(bindings: any, nodeName: string): string;
801
+ };
802
+
803
+ //////////////////////////////////
804
+ // nativeTemplateEngine.js
805
+ //////////////////////////////////
806
+
807
+ nativeTemplateEngine: {
808
+
809
+ prototype: KnockoutNativeTemplateEngine;
810
+
811
+ new(): KnockoutNativeTemplateEngine;
812
+
813
+ instance: KnockoutNativeTemplateEngine;
814
+ };
815
+
816
+ //////////////////////////////////
817
+ // jqueryTmplTemplateEngine.js
818
+ //////////////////////////////////
819
+
820
+ jqueryTmplTemplateEngine: {
821
+
822
+ prototype: KnockoutTemplateEngine;
823
+
824
+ renderTemplateSource(templateSource: Object, bindingContext: KnockoutBindingContext, options: Object): Node[];
825
+
826
+ createJavaScriptEvaluatorBlock(script: string): string;
827
+
828
+ addTemplate(templateName: string, templateMarkup: string): void;
829
+ };
830
+
831
+ //////////////////////////////////
832
+ // templating.js
833
+ //////////////////////////////////
834
+
835
+ setTemplateEngine(templateEngine: KnockoutNativeTemplateEngine | undefined): void;
836
+
837
+ renderTemplate(template: Function, dataOrBindingContext: KnockoutBindingContext, options: Object, targetNodeOrNodeArray: Node, renderMode: string): any;
838
+ renderTemplate(template: any, dataOrBindingContext: KnockoutBindingContext, options: Object, targetNodeOrNodeArray: Node, renderMode: string): any;
839
+ renderTemplate(template: Function, dataOrBindingContext: any, options: Object, targetNodeOrNodeArray: Node, renderMode: string): any;
840
+ renderTemplate(template: any, dataOrBindingContext: any, options: Object, targetNodeOrNodeArray: Node, renderMode: string): any;
841
+ renderTemplate(template: Function, dataOrBindingContext: KnockoutBindingContext, options: Object, targetNodeOrNodeArray: Node[], renderMode: string): any;
842
+ renderTemplate(template: any, dataOrBindingContext: KnockoutBindingContext, options: Object, targetNodeOrNodeArray: Node[], renderMode: string): any;
843
+ renderTemplate(template: Function, dataOrBindingContext: any, options: Object, targetNodeOrNodeArray: Node[], renderMode: string): any;
844
+ renderTemplate(template: any, dataOrBindingContext: any, options: Object, targetNodeOrNodeArray: Node[], renderMode: string): any;
845
+
846
+ renderTemplateForEach(template: Function, arrayOrObservableArray: any[], options: Object, targetNode: Node, parentBindingContext: KnockoutBindingContext): any;
847
+ renderTemplateForEach(template: any, arrayOrObservableArray: any[], options: Object, targetNode: Node, parentBindingContext: KnockoutBindingContext): any;
848
+ renderTemplateForEach(template: Function, arrayOrObservableArray: KnockoutObservable<any>, options: Object, targetNode: Node, parentBindingContext: KnockoutBindingContext): any;
849
+ renderTemplateForEach(template: any, arrayOrObservableArray: KnockoutObservable<any>, options: Object, targetNode: Node, parentBindingContext: KnockoutBindingContext): any;
850
+
851
+ /**
852
+ * Executes a callback function inside a computed observable, without creating a dependecy between it and the observables inside the function.
853
+ * @param callback Function to be called.
854
+ * @param callbackTarget Defines the value of 'this' in the callback function.
855
+ * @param callbackArgs Arguments for the callback Function.
856
+ */
857
+ ignoreDependencies<T>(callback: () => T, callbackTarget?: any, callbackArgs?: any): T;
858
+
859
+ expressionRewriting: {
860
+ bindingRewriteValidators: any[];
861
+ twoWayBindings: any;
862
+ parseObjectLiteral: (objectLiteralString: string) => any[];
863
+
864
+ /**
865
+ Internal, private KO utility for updating model properties from within bindings
866
+ property: If the property being updated is (or might be) an observable, pass it here
867
+ If it turns out to be a writable observable, it will be written to directly
868
+ allBindings: An object with a get method to retrieve bindings in the current execution context.
869
+ This will be searched for a '_ko_property_writers' property in case you're writing to a non-observable
870
+ (See note below)
871
+ key: The key identifying the property to be written. Example: for { hasFocus: myValue }, write to 'myValue' by specifying the key 'hasFocus'
872
+ value: The value to be written
873
+ checkIfDifferent: If true, and if the property being written is a writable observable, the value will only be written if
874
+ it is !== existing value on that writable observable
875
+
876
+ Note that if you need to write to the viewModel without an observable property,
877
+ you need to set ko.expressionRewriting.twoWayBindings[key] = true; *before* the binding evaluation.
878
+ */
879
+ writeValueToProperty: (property: KnockoutObservable<any> | any, allBindings: KnockoutAllBindingsAccessor, key: string, value: any, checkIfDifferent?: boolean) => void;
880
+ };
881
+
882
+ /////////////////////////////////
883
+
884
+ bindingProvider: {
885
+ instance: KnockoutBindingProvider;
886
+ new(): KnockoutBindingProvider;
887
+ }
888
+
889
+ /////////////////////////////////
890
+ // selectExtensions.js
891
+ /////////////////////////////////
892
+
893
+ selectExtensions: {
894
+
895
+ readValue(element: HTMLElement): any;
896
+
897
+ writeValue(element: HTMLElement, value: any, allowUnset?: boolean): void;
898
+ };
899
+
900
+ components: KnockoutComponents;
901
+
902
+ /////////////////////////////////
903
+ // options.js
904
+ /////////////////////////////////
905
+
906
+ options: {
907
+ deferUpdates: boolean,
908
+
909
+ useOnlyNativeEvents: boolean
910
+ };
911
+
912
+ /////////////////////////////////
913
+ // tasks.js
914
+ /////////////////////////////////
915
+
916
+ tasks: KnockoutTasks;
917
+
918
+ /////////////////////////////////
919
+ // utils.js
920
+ /////////////////////////////////
921
+
922
+ onError?: (error: Error) => void;
923
+ }
924
+
925
+ interface KnockoutBindingProvider {
926
+ nodeHasBindings(node: Node): boolean;
927
+ getBindings(node: Node, bindingContext: KnockoutBindingContext): {};
928
+ getBindingAccessors?(node: Node, bindingContext: KnockoutBindingContext): { [key: string]: string; };
929
+ }
930
+
931
+ interface KnockoutComputedContext {
932
+ /**
933
+ * Returns the number of dependencies of the computed observable detected so far during the current evaluation.
934
+ */
935
+ getDependenciesCount(): number;
936
+ /**
937
+ * A function that returns true if called during the first ever evaluation of the current computed observable, or false otherwise.
938
+ * For pure computed observables, isInitial() is always undefined.
939
+ */
940
+ isInitial: () => boolean;
941
+ isSleeping: boolean;
942
+ }
943
+
944
+ //
945
+ // refactored types into a namespace to reduce global pollution
946
+ // and used Union Types to simplify overloads (requires TypeScript 1.4)
947
+ //
948
+ declare namespace KnockoutComponentTypes {
949
+
950
+ interface Config {
951
+ viewModel?: ViewModelFunction | ViewModelSharedInstance | ViewModelFactoryFunction | AMDModule;
952
+ template: string | Node[] | DocumentFragment | TemplateElement | AMDModule;
953
+ synchronous?: boolean;
954
+ }
955
+
956
+ interface ComponentConfig {
957
+ viewModel?: ViewModelFunction | ViewModelSharedInstance | ViewModelFactoryFunction | AMDModule;
958
+ template: any;
959
+ createViewModel?: any;
960
+ }
961
+
962
+ interface EmptyConfig {
963
+ }
964
+
965
+ // common AMD type
966
+ interface AMDModule {
967
+ require: string;
968
+ }
969
+
970
+ // viewmodel types
971
+ interface ViewModelFunction {
972
+ (params?: any): any;
973
+ }
974
+
975
+ interface ViewModelSharedInstance {
976
+ instance: any;
977
+ }
978
+
979
+ interface ViewModelFactoryFunction {
980
+ createViewModel: (params: any, componentInfo: ComponentInfo) => any;
981
+ }
982
+
983
+ interface ComponentInfo {
984
+ element: Node;
985
+ templateNodes: Node[];
986
+ }
987
+
988
+ interface TemplateElement {
989
+ element: string | Node;
990
+ }
991
+
992
+ interface Loader {
993
+ /**
994
+ * Define this if: you want to supply configurations programmatically based on names, e.g., to implement a naming convention.
995
+ * @see {@link https://knockoutjs.com/documentation/component-loaders.html}
996
+ */
997
+ getConfig?(componentName: string, callback: (result: ComponentConfig | null) => void): void;
998
+ /**
999
+ * Define this if: you want to take control over how component configurations are interpreted, e.g., if you do not want to use the standard 'viewModel/template' pair format.
1000
+ * @see {@link https://knockoutjs.com/documentation/component-loaders.html}
1001
+ */
1002
+ loadComponent?(componentName: string, config: ComponentConfig, callback: (result: Definition | null) => void): void;
1003
+ /**
1004
+ * Define this if: you want to use custom logic to supply DOM nodes for a given template configuration (e.g., using an ajax request to fetch a template by URL).
1005
+ * @see {@link https://knockoutjs.com/documentation/component-loaders.html}
1006
+ */
1007
+ loadTemplate?(componentName: string, templateConfig: any, callback: (result: Node[] | null) => void): void;
1008
+ /**
1009
+ * Define this if: you want to use custom logic to supply a viewmodel factory for a given viewmodel configuration (e.g., integrating with a third-party module loader or dependency injection system).
1010
+ * @see {@link https://knockoutjs.com/documentation/component-loaders.html}
1011
+ */
1012
+ loadViewModel?(componentName: string, viewModelConfig: any, callback: (result: any) => void): void;
1013
+ suppressLoaderExceptions?: boolean;
1014
+ }
1015
+
1016
+ interface Definition {
1017
+ template: Node[];
1018
+ createViewModel?(params: any, options: { element: Node; }): any;
1019
+ }
1020
+ }
1021
+
1022
+ interface KnockoutComponents {
1023
+
1024
+ /**
1025
+ * Registers a component, in the default component loader, to be used by name in the component binding.
1026
+ * @param componentName Component name. Will be used for your custom HTML tag name.
1027
+ * @param config Component configuration.
1028
+ */
1029
+ register(componentName: string, config: KnockoutComponentTypes.Config | KnockoutComponentTypes.EmptyConfig): void;
1030
+ /**
1031
+ * Determine if a component with the specified name is already registered in the default component loader.
1032
+ * @param componentName Component name.
1033
+ */
1034
+ isRegistered(componentName: string): boolean;
1035
+ /**
1036
+ * Removes the named component from the default component loader registry. Or if no such component was registered, does nothing.
1037
+ * @param componentName Component name.
1038
+ */
1039
+ unregister(componentName: string): void;
1040
+ /**
1041
+ * Searchs each registered component loader by component name, and returns the viewmodel/template declaration via callback parameter.
1042
+ * @param componentName Component name.
1043
+ * @param callback Function to be called with the viewmodel/template declaration parameter.
1044
+ */
1045
+ get(componentName: string, callback: (definition: KnockoutComponentTypes.Definition) => void): void;
1046
+ /**
1047
+ * Clears the cache knockout creates to speed up component loading, for a given component.
1048
+ * @param componentName Component name.
1049
+ */
1050
+ clearCachedDefinition(componentName: string): void
1051
+ defaultLoader: KnockoutComponentTypes.Loader;
1052
+ loaders: KnockoutComponentTypes.Loader[];
1053
+ /**
1054
+ * Returns the registered component name for a HTML element. Can be overwriten to to control dynamically which HTML element map to which component name.
1055
+ * @param node html element that corresponds to a custom component.
1056
+ */
1057
+ getComponentNameForNode(node: Node): string;
1058
+ }
1059
+
1060
+ declare var ko: KnockoutStatic;
1061
+
1062
+ declare module "knockout" {
1063
+ export = ko;
1064
+ }
js/knockout.js CHANGED
@@ -1,124 +1,139 @@
1
/*!
2
- * Knockout JavaScript library v3.4.2
3
* (c) The Knockout.js team - http://knockoutjs.com/
4
* License: MIT (http://www.opensource.org/licenses/mit-license.php)
5
*/
6
7
- (function() {(function(n){var x=this||(0,eval)("this"),t=x.document,M=x.navigator,u=x.jQuery,H=x.JSON;(function(n){"function"===typeof define&&define.amd?define(["exports","require"],n):"object"===typeof exports&&"object"===typeof module?n(module.exports||exports):n(x.ko={})})(function(N,O){function J(a,c){return null===a||typeof a in R?a===c:!1}function S(b,c){var d;return function(){d||(d=a.a.setTimeout(function(){d=n;b()},c))}}function T(b,c){var d;return function(){clearTimeout(d);d=a.a.setTimeout(b,c)}}function U(a,
8
- c){c&&c!==E?"beforeChange"===c?this.Ob(a):this.Ja(a,c):this.Pb(a)}function V(a,c){null!==c&&c.k&&c.k()}function W(a,c){var d=this.Mc,e=d[s];e.T||(this.ob&&this.Oa[c]?(d.Sb(c,a,this.Oa[c]),this.Oa[c]=null,--this.ob):e.s[c]||d.Sb(c,a,e.t?{$:a}:d.yc(a)),a.Ha&&a.Hc())}function K(b,c,d,e){a.d[b]={init:function(b,g,h,l,m){var k,r;a.m(function(){var q=g(),p=a.a.c(q),p=!d!==!p,A=!r;if(A||c||p!==k)A&&a.xa.Ca()&&(r=a.a.wa(a.f.childNodes(b),!0)),p?(A||a.f.fa(b,a.a.wa(r)),a.hb(e?e(m,q):m,b)):a.f.za(b),k=p},null,
9
- {i:b});return{controlsDescendantBindings:!0}}};a.h.va[b]=!1;a.f.aa[b]=!0}var a="undefined"!==typeof N?N:{};a.b=function(b,c){for(var d=b.split("."),e=a,f=0;f<d.length-1;f++)e=e[d[f]];e[d[d.length-1]]=c};a.H=function(a,c,d){a[c]=d};a.version="3.4.2";a.b("version",a.version);a.options={deferUpdates:!1,useOnlyNativeEvents:!1};a.a=function(){function b(a,b){for(var c in a)a.hasOwnProperty(c)&&b(c,a[c])}function c(a,b){if(b)for(var c in b)b.hasOwnProperty(c)&&(a[c]=b[c]);return a}function d(a,b){a.__proto__=
10
- b;return a}function e(b,c,d,e){var m=b[c].match(r)||[];a.a.r(d.match(r),function(b){a.a.ra(m,b,e)});b[c]=m.join(" ")}var f={__proto__:[]}instanceof Array,g="function"===typeof Symbol,h={},l={};h[M&&/Firefox\/2/i.test(M.userAgent)?"KeyboardEvent":"UIEvents"]=["keyup","keydown","keypress"];h.MouseEvents="click dblclick mousedown mouseup mousemove mouseover mouseout mouseenter mouseleave".split(" ");b(h,function(a,b){if(b.length)for(var c=0,d=b.length;c<d;c++)l[b[c]]=a});var m={propertychange:!0},k=
11
- t&&function(){for(var a=3,b=t.createElement("div"),c=b.getElementsByTagName("i");b.innerHTML="\x3c!--[if gt IE "+ ++a+"]><i></i><![endif]--\x3e",c[0];);return 4<a?a:n}(),r=/\S+/g;return{gc:["authenticity_token",/^__RequestVerificationToken(_.*)?#x2F;],r:function(a,b){for(var c=0,d=a.length;c<d;c++)b(a[c],c)},o:function(a,b){if("function"==typeof Array.prototype.indexOf)return Array.prototype.indexOf.call(a,b);for(var c=0,d=a.length;c<d;c++)if(a[c]===b)return c;return-1},Vb:function(a,b,c){for(var d=
12
- 0,e=a.length;d<e;d++)if(b.call(c,a[d],d))return a[d];return null},Na:function(b,c){var d=a.a.o(b,c);0<d?b.splice(d,1):0===d&&b.shift()},Wb:function(b){b=b||[];for(var c=[],d=0,e=b.length;d<e;d++)0>a.a.o(c,b[d])&&c.push(b[d]);return c},ib:function(a,b){a=a||[];for(var c=[],d=0,e=a.length;d<e;d++)c.push(b(a[d],d));return c},Ma:function(a,b){a=a||[];for(var c=[],d=0,e=a.length;d<e;d++)b(a[d],d)&&c.push(a[d]);return c},ta:function(a,b){if(b instanceof Array)a.push.apply(a,b);else for(var c=0,d=b.length;c<
13
- d;c++)a.push(b[c]);return a},ra:function(b,c,d){var e=a.a.o(a.a.Bb(b),c);0>e?d&&b.push(c):d||b.splice(e,1)},la:f,extend:c,$a:d,ab:f?d:c,D:b,Ea:function(a,b){if(!a)return a;var c={},d;for(d in a)a.hasOwnProperty(d)&&(c[d]=b(a[d],d,a));return c},rb:function(b){for(;b.firstChild;)a.removeNode(b.firstChild)},nc:function(b){b=a.a.W(b);for(var c=(b[0]&&b[0].ownerDocument||t).createElement("div"),d=0,e=b.length;d<e;d++)c.appendChild(a.ba(b[d]));return c},wa:function(b,c){for(var d=0,e=b.length,m=[];d<e;d++){var k=
14
- b[d].cloneNode(!0);m.push(c?a.ba(k):k)}return m},fa:function(b,c){a.a.rb(b);if(c)for(var d=0,e=c.length;d<e;d++)b.appendChild(c[d])},uc:function(b,c){var d=b.nodeType?[b]:b;if(0<d.length){for(var e=d[0],m=e.parentNode,k=0,f=c.length;k<f;k++)m.insertBefore(c[k],e);k=0;for(f=d.length;k<f;k++)a.removeNode(d[k])}},Ba:function(a,b){if(a.length){for(b=8===b.nodeType&&b.parentNode||b;a.length&&a[0].parentNode!==b;)a.splice(0,1);for(;1<a.length&&a[a.length-1].parentNode!==b;)a.length--;if(1<a.length){var c=
15
- a[0],d=a[a.length-1];for(a.length=0;c!==d;)a.push(c),c=c.nextSibling;a.push(d)}}return a},wc:function(a,b){7>k?a.setAttribute("selected",b):a.selected=b},cb:function(a){return null===a||a===n?"":a.trim?a.trim():a.toString().replace(/^[\s\xa0]+|[\s\xa0]+#x2F;g,"")},sd:function(a,b){a=a||"";return b.length>a.length?!1:a.substring(0,b.length)===b},Rc:function(a,b){if(a===b)return!0;if(11===a.nodeType)return!1;if(b.contains)return b.contains(3===a.nodeType?a.parentNode:a);if(b.compareDocumentPosition)return 16==
16
- (b.compareDocumentPosition(a)&16);for(;a&&a!=b;)a=a.parentNode;return!!a},qb:function(b){return a.a.Rc(b,b.ownerDocument.documentElement)},Tb:function(b){return!!a.a.Vb(b,a.a.qb)},A:function(a){return a&&a.tagName&&a.tagName.toLowerCase()},Zb:function(b){return a.onError?function(){try{return b.apply(this,arguments)}catch(c){throw a.onError&&a.onError(c),c;}}:b},setTimeout:function(b,c){return setTimeout(a.a.Zb(b),c)},dc:function(b){setTimeout(function(){a.onError&&a.onError(b);throw b;},0)},q:function(b,
17
- c,d){var e=a.a.Zb(d);d=k&&m[c];if(a.options.useOnlyNativeEvents||d||!u)if(d||"function"!=typeof b.addEventListener)if("undefined"!=typeof b.attachEvent){var f=function(a){e.call(b,a)},l="on"+c;b.attachEvent(l,f);a.a.G.qa(b,function(){b.detachEvent(l,f)})}else throw Error("Browser doesn't support addEventListener or attachEvent");else b.addEventListener(c,e,!1);else u(b).bind(c,e)},Fa:function(b,c){if(!b||!b.nodeType)throw Error("element must be a DOM node when calling triggerEvent");var d;"input"===
18
- a.a.A(b)&&b.type&&"click"==c.toLowerCase()?(d=b.type,d="checkbox"==d||"radio"==d):d=!1;if(a.options.useOnlyNativeEvents||!u||d)if("function"==typeof t.createEvent)if("function"==typeof b.dispatchEvent)d=t.createEvent(l[c]||"HTMLEvents"),d.initEvent(c,!0,!0,x,0,0,0,0,0,!1,!1,!1,!1,0,b),b.dispatchEvent(d);else throw Error("The supplied element doesn't support dispatchEvent");else if(d&&b.click)b.click();else if("undefined"!=typeof b.fireEvent)b.fireEvent("on"+c);else throw Error("Browser doesn't support triggering events");
19
- else u(b).trigger(c)},c:function(b){return a.I(b)?b():b},Bb:function(b){return a.I(b)?b.p():b},fb:function(b,c,d){var k;c&&("object"===typeof b.classList?(k=b.classList[d?"add":"remove"],a.a.r(c.match(r),function(a){k.call(b.classList,a)})):"string"===typeof b.className.baseVal?e(b.className,"baseVal",c,d):e(b,"className",c,d))},bb:function(b,c){var d=a.a.c(c);if(null===d||d===n)d="";var e=a.f.firstChild(b);!e||3!=e.nodeType||a.f.nextSibling(e)?a.f.fa(b,[b.ownerDocument.createTextNode(d)]):e.data=
20
- d;a.a.Wc(b)},vc:function(a,b){a.name=b;if(7>=k)try{a.mergeAttributes(t.createElement("<input name='"+a.name+"'/>"),!1)}catch(c){}},Wc:function(a){9<=k&&(a=1==a.nodeType?a:a.parentNode,a.style&&(a.style.zoom=a.style.zoom))},Sc:function(a){if(k){var b=a.style.width;a.style.width=0;a.style.width=b}},nd:function(b,c){b=a.a.c(b);c=a.a.c(c);for(var d=[],e=b;e<=c;e++)d.push(e);return d},W:function(a){for(var b=[],c=0,d=a.length;c<d;c++)b.push(a[c]);return b},bc:function(a){return g?Symbol(a):a},xd:6===k,
21
- yd:7===k,C:k,ic:function(b,c){for(var d=a.a.W(b.getElementsByTagName("input")).concat(a.a.W(b.getElementsByTagName("textarea"))),e="string"==typeof c?function(a){return a.name===c}:function(a){return c.test(a.name)},k=[],m=d.length-1;0<=m;m--)e(d[m])&&k.push(d[m]);return k},kd:function(b){return"string"==typeof b&&(b=a.a.cb(b))?H&&H.parse?H.parse(b):(new Function("return "+b))():null},Gb:function(b,c,d){if(!H||!H.stringify)throw Error("Cannot find JSON.stringify(). Some browsers (e.g., IE < 8) don't support it natively, but you can overcome this by adding a script reference to json2.js, downloadable from http://www.json.org/json2.js");
22
- return H.stringify(a.a.c(b),c,d)},ld:function(c,d,e){e=e||{};var k=e.params||{},m=e.includeFields||this.gc,f=c;if("object"==typeof c&&"form"===a.a.A(c))for(var f=c.action,l=m.length-1;0<=l;l--)for(var g=a.a.ic(c,m[l]),h=g.length-1;0<=h;h--)k[g[h].name]=g[h].value;d=a.a.c(d);var r=t.createElement("form");r.style.display="none";r.action=f;r.method="post";for(var n in d)c=t.createElement("input"),c.type="hidden",c.name=n,c.value=a.a.Gb(a.a.c(d[n])),r.appendChild(c);b(k,function(a,b){var c=t.createElement("input");
23
- c.type="hidden";c.name=a;c.value=b;r.appendChild(c)});t.body.appendChild(r);e.submitter?e.submitter(r):r.submit();setTimeout(function(){r.parentNode.removeChild(r)},0)}}}();a.b("utils",a.a);a.b("utils.arrayForEach",a.a.r);a.b("utils.arrayFirst",a.a.Vb);a.b("utils.arrayFilter",a.a.Ma);a.b("utils.arrayGetDistinctValues",a.a.Wb);a.b("utils.arrayIndexOf",a.a.o);a.b("utils.arrayMap",a.a.ib);a.b("utils.arrayPushAll",a.a.ta);a.b("utils.arrayRemoveItem",a.a.Na);a.b("utils.extend",a.a.extend);a.b("utils.fieldsIncludedWithJsonPost",
24
- a.a.gc);a.b("utils.getFormFields",a.a.ic);a.b("utils.peekObservable",a.a.Bb);a.b("utils.postJson",a.a.ld);a.b("utils.parseJson",a.a.kd);a.b("utils.registerEventHandler",a.a.q);a.b("utils.stringifyJson",a.a.Gb);a.b("utils.range",a.a.nd);a.b("utils.toggleDomNodeCssClass",a.a.fb);a.b("utils.triggerEvent",a.a.Fa);a.b("utils.unwrapObservable",a.a.c);a.b("utils.objectForEach",a.a.D);a.b("utils.addOrRemoveItem",a.a.ra);a.b("utils.setTextContent",a.a.bb);a.b("unwrap",a.a.c);Function.prototype.bind||(Function.prototype.bind=
25
- function(a){var c=this;if(1===arguments.length)return function(){return c.apply(a,arguments)};var d=Array.prototype.slice.call(arguments,1);return function(){var e=d.slice(0);e.push.apply(e,arguments);return c.apply(a,e)}});a.a.e=new function(){function a(b,g){var h=b[d];if(!h||"null"===h||!e[h]){if(!g)return n;h=b[d]="ko"+c++;e[h]={}}return e[h]}var c=0,d="__ko__"+(new Date).getTime(),e={};return{get:function(c,d){var e=a(c,!1);return e===n?n:e[d]},set:function(c,d,e){if(e!==n||a(c,!1)!==n)a(c,!0)[d]=
26
- e},clear:function(a){var b=a[d];return b?(delete e[b],a[d]=null,!0):!1},J:function(){return c++ +d}}};a.b("utils.domData",a.a.e);a.b("utils.domData.clear",a.a.e.clear);a.a.G=new function(){function b(b,c){var e=a.a.e.get(b,d);e===n&&c&&(e=[],a.a.e.set(b,d,e));return e}function c(d){var e=b(d,!1);if(e)for(var e=e.slice(0),l=0;l<e.length;l++)e[l](d);a.a.e.clear(d);a.a.G.cleanExternalData(d);if(f[d.nodeType])for(e=d.firstChild;d=e;)e=d.nextSibling,8===d.nodeType&&c(d)}var d=a.a.e.J(),e={1:!0,8:!0,9:!0},
27
- f={1:!0,9:!0};return{qa:function(a,c){if("function"!=typeof c)throw Error("Callback must be a function");b(a,!0).push(c)},tc:function(c,e){var f=b(c,!1);f&&(a.a.Na(f,e),0==f.length&&a.a.e.set(c,d,n))},ba:function(b){if(e[b.nodeType]&&(c(b),f[b.nodeType])){var d=[];a.a.ta(d,b.getElementsByTagName("*"));for(var l=0,m=d.length;l<m;l++)c(d[l])}return b},removeNode:function(b){a.ba(b);b.parentNode&&b.parentNode.removeChild(b)},cleanExternalData:function(a){u&&"function"==typeof u.cleanData&&u.cleanData([a])}}};
28
- a.ba=a.a.G.ba;a.removeNode=a.a.G.removeNode;a.b("cleanNode",a.ba);a.b("removeNode",a.removeNode);a.b("utils.domNodeDisposal",a.a.G);a.b("utils.domNodeDisposal.addDisposeCallback",a.a.G.qa);a.b("utils.domNodeDisposal.removeDisposeCallback",a.a.G.tc);(function(){var b=[0,"",""],c=[1,"<table>","</table>"],d=[3,"<table><tbody><tr>","</tr></tbody></table>"],e=[1,"<select multiple='multiple'>","</select>"],f={thead:c,tbody:c,tfoot:c,tr:[2,"<table><tbody>","</tbody></table>"],td:d,th:d,option:e,optgroup:e},
29
- g=8>=a.a.C;a.a.na=function(c,d){var e;if(u)if(u.parseHTML)e=u.parseHTML(c,d)||[];else{if((e=u.clean([c],d))&&e[0]){for(var k=e[0];k.parentNode&&11!==k.parentNode.nodeType;)k=k.parentNode;k.parentNode&&k.parentNode.removeChild(k)}}else{(e=d)||(e=t);var k=e.parentWindow||e.defaultView||x,r=a.a.cb(c).toLowerCase(),q=e.createElement("div"),p;p=(r=r.match(/^<([a-z]+)[ >]/))&&f[r[1]]||b;r=p[0];p="ignored<div>"+p[1]+c+p[2]+"</div>";"function"==typeof k.innerShiv?q.appendChild(k.innerShiv(p)):(g&&e.appendChild(q),
30
- q.innerHTML=p,g&&q.parentNode.removeChild(q));for(;r--;)q=q.lastChild;e=a.a.W(q.lastChild.childNodes)}return e};a.a.Eb=function(b,c){a.a.rb(b);c=a.a.c(c);if(null!==c&&c!==n)if("string"!=typeof c&&(c=c.toString()),u)u(b).html(c);else for(var d=a.a.na(c,b.ownerDocument),e=0;e<d.length;e++)b.appendChild(d[e])}})();a.b("utils.parseHtmlFragment",a.a.na);a.b("utils.setHtml",a.a.Eb);a.N=function(){function b(c,e){if(c)if(8==c.nodeType){var f=a.N.pc(c.nodeValue);null!=f&&e.push({Qc:c,hd:f})}else if(1==c.nodeType)for(var f=
31
- 0,g=c.childNodes,h=g.length;f<h;f++)b(g[f],e)}var c={};return{yb:function(a){if("function"!=typeof a)throw Error("You can only pass a function to ko.memoization.memoize()");var b=(4294967296*(1+Math.random())|0).toString(16).substring(1)+(4294967296*(1+Math.random())|0).toString(16).substring(1);c[b]=a;return"\x3c!--[ko_memo:"+b+"]--\x3e"},Bc:function(a,b){var f=c[a];if(f===n)throw Error("Couldn't find any memo with ID "+a+". Perhaps it's already been unmemoized.");try{return f.apply(null,b||[]),
32
- !0}finally{delete c[a]}},Cc:function(c,e){var f=[];b(c,f);for(var g=0,h=f.length;g<h;g++){var l=f[g].Qc,m=[l];e&&a.a.ta(m,e);a.N.Bc(f[g].hd,m);l.nodeValue="";l.parentNode&&l.parentNode.removeChild(l)}},pc:function(a){return(a=a.match(/^\[ko_memo\:(.*?)\]#x2F;))?a[1]:null}}}();a.b("memoization",a.N);a.b("memoization.memoize",a.N.yb);a.b("memoization.unmemoize",a.N.Bc);a.b("memoization.parseMemoText",a.N.pc);a.b("memoization.unmemoizeDomNodeAndDescendants",a.N.Cc);a.Z=function(){function b(){if(e)for(var b=
33
- e,c=0,m;g<e;)if(m=d[g++]){if(g>b){if(5E3<=++c){g=e;a.a.dc(Error("'Too much recursion' after processing "+c+" task groups."));break}b=e}try{m()}catch(k){a.a.dc(k)}}}function c(){b();g=e=d.length=0}var d=[],e=0,f=1,g=0;return{scheduler:x.MutationObserver?function(a){var b=t.createElement("div");(new MutationObserver(a)).observe(b,{attributes:!0});return function(){b.classList.toggle("foo")}}(c):t&&"onreadystatechange"in t.createElement("script")?function(a){var b=t.createElement("script");b.onreadystatechange=
34
- function(){b.onreadystatechange=null;t.documentElement.removeChild(b);b=null;a()};t.documentElement.appendChild(b)}:function(a){setTimeout(a,0)},Za:function(b){e||a.Z.scheduler(c);d[e++]=b;return f++},cancel:function(a){a-=f-e;a>=g&&a<e&&(d[a]=null)},resetForTesting:function(){var a=e-g;g=e=d.length=0;return a},rd:b}}();a.b("tasks",a.Z);a.b("tasks.schedule",a.Z.Za);a.b("tasks.runEarly",a.Z.rd);a.Aa={throttle:function(b,c){b.throttleEvaluation=c;var d=null;return a.B({read:b,write:function(e){clearTimeout(d);
35
- d=a.a.setTimeout(function(){b(e)},c)}})},rateLimit:function(a,c){var d,e,f;"number"==typeof c?d=c:(d=c.timeout,e=c.method);a.gb=!1;f="notifyWhenChangesStop"==e?T:S;a.Wa(function(a){return f(a,d)})},deferred:function(b,c){if(!0!==c)throw Error("The 'deferred' extender only accepts the value 'true', because it is not supported to turn deferral off once enabled.");b.gb||(b.gb=!0,b.Wa(function(c){var e,f=!1;return function(){if(!f){a.Z.cancel(e);e=a.Z.Za(c);try{f=!0,b.notifySubscribers(n,"dirty")}finally{f=
36
- !1}}}}))},notify:function(a,c){a.equalityComparer="always"==c?null:J}};var R={undefined:1,"boolean":1,number:1,string:1};a.b("extenders",a.Aa);a.zc=function(b,c,d){this.$=b;this.jb=c;this.Pc=d;this.T=!1;a.H(this,"dispose",this.k)};a.zc.prototype.k=function(){this.T=!0;this.Pc()};a.K=function(){a.a.ab(this,D);D.ub(this)};var E="change",D={ub:function(a){a.F={change:[]};a.Qb=1},Y:function(b,c,d){var e=this;d=d||E;var f=new a.zc(e,c?b.bind(c):b,function(){a.a.Na(e.F[d],f);e.Ka&&e.Ka(d)});e.ua&&e.ua(d);
37
- e.F[d]||(e.F[d]=[]);e.F[d].push(f);return f},notifySubscribers:function(b,c){c=c||E;c===E&&this.Kb();if(this.Ra(c)){var d=c===E&&this.Fc||this.F[c].slice(0);try{a.l.Xb();for(var e=0,f;f=d[e];++e)f.T||f.jb(b)}finally{a.l.end()}}},Pa:function(){return this.Qb},Zc:function(a){return this.Pa()!==a},Kb:function(){++this.Qb},Wa:function(b){var c=this,d=a.I(c),e,f,g,h;c.Ja||(c.Ja=c.notifySubscribers,c.notifySubscribers=U);var l=b(function(){c.Ha=!1;d&&h===c&&(h=c.Mb?c.Mb():c());var a=f||c.Ua(g,h);f=e=!1;
38
- a&&c.Ja(g=h)});c.Pb=function(a){c.Fc=c.F[E].slice(0);c.Ha=e=!0;h=a;l()};c.Ob=function(a){e||(g=a,c.Ja(a,"beforeChange"))};c.Hc=function(){c.Ua(g,c.p(!0))&&(f=!0)}},Ra:function(a){return this.F[a]&&this.F[a].length},Xc:function(b){if(b)return this.F[b]&&this.F[b].length||0;var c=0;a.a.D(this.F,function(a,b){"dirty"!==a&&(c+=b.length)});return c},Ua:function(a,c){return!this.equalityComparer||!this.equalityComparer(a,c)},extend:function(b){var c=this;b&&a.a.D(b,function(b,e){var f=a.Aa[b];"function"==
39
- typeof f&&(c=f(c,e)||c)});return c}};a.H(D,"subscribe",D.Y);a.H(D,"extend",D.extend);a.H(D,"getSubscriptionsCount",D.Xc);a.a.la&&a.a.$a(D,Function.prototype);a.K.fn=D;a.lc=function(a){return null!=a&&"function"==typeof a.Y&&"function"==typeof a.notifySubscribers};a.b("subscribable",a.K);a.b("isSubscribable",a.lc);a.xa=a.l=function(){function b(a){d.push(e);e=a}function c(){e=d.pop()}var d=[],e,f=0;return{Xb:b,end:c,sc:function(b){if(e){if(!a.lc(b))throw Error("Only subscribable things can act as dependencies");
40
- e.jb.call(e.Lc,b,b.Gc||(b.Gc=++f))}},w:function(a,d,e){try{return b(),a.apply(d,e||[])}finally{c()}},Ca:function(){if(e)return e.m.Ca()},Va:function(){if(e)return e.Va}}}();a.b("computedContext",a.xa);a.b("computedContext.getDependenciesCount",a.xa.Ca);a.b("computedContext.isInitial",a.xa.Va);a.b("ignoreDependencies",a.wd=a.l.w);var F=a.a.bc("_latestValue");a.O=function(b){function c(){if(0<arguments.length)return c.Ua(c[F],arguments[0])&&(c.ia(),c[F]=arguments[0],c.ha()),this;a.l.sc(c);return c[F]}
41
- c[F]=b;a.a.la||a.a.extend(c,a.K.fn);a.K.fn.ub(c);a.a.ab(c,B);a.options.deferUpdates&&a.Aa.deferred(c,!0);return c};var B={equalityComparer:J,p:function(){return this[F]},ha:function(){this.notifySubscribers(this[F])},ia:function(){this.notifySubscribers(this[F],"beforeChange")}};a.a.la&&a.a.$a(B,a.K.fn);var I=a.O.md="__ko_proto__";B[I]=a.O;a.Qa=function(b,c){return null===b||b===n||b[I]===n?!1:b[I]===c?!0:a.Qa(b[I],c)};a.I=function(b){return a.Qa(b,a.O)};a.Da=function(b){return"function"==typeof b&&
42
- b[I]===a.O||"function"==typeof b&&b[I]===a.B&&b.$c?!0:!1};a.b("observable",a.O);a.b("isObservable",a.I);a.b("isWriteableObservable",a.Da);a.b("isWritableObservable",a.Da);a.b("observable.fn",B);a.H(B,"peek",B.p);a.H(B,"valueHasMutated",B.ha);a.H(B,"valueWillMutate",B.ia);a.ma=function(b){b=b||[];if("object"!=typeof b||!("length"in b))throw Error("The argument passed when initializing an observable array must be an array, or null, or undefined.");b=a.O(b);a.a.ab(b,a.ma.fn);return b.extend({trackArrayChanges:!0})};
43
- a.ma.fn={remove:function(b){for(var c=this.p(),d=[],e="function"!=typeof b||a.I(b)?function(a){return a===b}:b,f=0;f<c.length;f++){var g=c[f];e(g)&&(0===d.length&&this.ia(),d.push(g),c.splice(f,1),f--)}d.length&&this.ha();return d},removeAll:function(b){if(b===n){var c=this.p(),d=c.slice(0);this.ia();c.splice(0,c.length);this.ha();return d}return b?this.remove(function(c){return 0<=a.a.o(b,c)}):[]},destroy:function(b){var c=this.p(),d="function"!=typeof b||a.I(b)?function(a){return a===b}:b;this.ia();
44
- for(var e=c.length-1;0<=e;e--)d(c[e])&&(c[e]._destroy=!0);this.ha()},destroyAll:function(b){return b===n?this.destroy(function(){return!0}):b?this.destroy(function(c){return 0<=a.a.o(b,c)}):[]},indexOf:function(b){var c=this();return a.a.o(c,b)},replace:function(a,c){var d=this.indexOf(a);0<=d&&(this.ia(),this.p()[d]=c,this.ha())}};a.a.la&&a.a.$a(a.ma.fn,a.O.fn);a.a.r("pop push reverse shift sort splice unshift".split(" "),function(b){a.ma.fn[b]=function(){var a=this.p();this.ia();this.Yb(a,b,arguments);
45
- var d=a[b].apply(a,arguments);this.ha();return d===a?this:d}});a.a.r(["slice"],function(b){a.ma.fn[b]=function(){var a=this();return a[b].apply(a,arguments)}});a.b("observableArray",a.ma);a.Aa.trackArrayChanges=function(b,c){function d(){if(!e){e=!0;l=b.notifySubscribers;b.notifySubscribers=function(a,b){b&&b!==E||++h;return l.apply(this,arguments)};var c=[].concat(b.p()||[]);f=null;g=b.Y(function(d){d=[].concat(d||[]);if(b.Ra("arrayChange")){var e;if(!f||1<h)f=a.a.lb(c,d,b.kb);e=f}c=d;f=null;h=0;
46
- e&&e.length&&b.notifySubscribers(e,"arrayChange")})}}b.kb={};c&&"object"==typeof c&&a.a.extend(b.kb,c);b.kb.sparse=!0;if(!b.Yb){var e=!1,f=null,g,h=0,l,m=b.ua,k=b.Ka;b.ua=function(a){m&&m.call(b,a);"arrayChange"===a&&d()};b.Ka=function(a){k&&k.call(b,a);"arrayChange"!==a||b.Ra("arrayChange")||(l&&(b.notifySubscribers=l,l=n),g.k(),e=!1)};b.Yb=function(b,c,d){function k(a,b,c){return m[m.length]={status:a,value:b,index:c}}if(e&&!h){var m=[],l=b.length,g=d.length,G=0;switch(c){case "push":G=l;case "unshift":for(c=
47
- 0;c<g;c++)k("added",d[c],G+c);break;case "pop":G=l-1;case "shift":l&&k("deleted",b[G],G);break;case "splice":c=Math.min(Math.max(0,0>d[0]?l+d[0]:d[0]),l);for(var l=1===g?l:Math.min(c+(d[1]||0),l),g=c+g-2,G=Math.max(l,g),n=[],s=[],w=2;c<G;++c,++w)c<l&&s.push(k("deleted",b[c],c)),c<g&&n.push(k("added",d[w],c));a.a.hc(s,n);break;default:return}f=m}}}};var s=a.a.bc("_state");a.m=a.B=function(b,c,d){function e(){if(0<arguments.length){if("function"===typeof f)f.apply(g.sb,arguments);else throw Error("Cannot write a value to a ko.computed unless you specify a 'write' option. If you wish to read the current value, don't pass any parameters.");
48
- return this}a.l.sc(e);(g.V||g.t&&e.Sa())&&e.U();return g.M}"object"===typeof b?d=b:(d=d||{},b&&(d.read=b));if("function"!=typeof d.read)throw Error("Pass a function that returns the value of the ko.computed");var f=d.write,g={M:n,da:!0,V:!0,Ta:!1,Hb:!1,T:!1,Ya:!1,t:!1,od:d.read,sb:c||d.owner,i:d.disposeWhenNodeIsRemoved||d.i||null,ya:d.disposeWhen||d.ya,pb:null,s:{},L:0,fc:null};e[s]=g;e.$c="function"===typeof f;a.a.la||a.a.extend(e,a.K.fn);a.K.fn.ub(e);a.a.ab(e,z);d.pure?(g.Ya=!0,g.t=!0,a.a.extend(e,
49
- Y)):d.deferEvaluation&&a.a.extend(e,Z);a.options.deferUpdates&&a.Aa.deferred(e,!0);g.i&&(g.Hb=!0,g.i.nodeType||(g.i=null));g.t||d.deferEvaluation||e.U();g.i&&e.ca()&&a.a.G.qa(g.i,g.pb=function(){e.k()});return e};var z={equalityComparer:J,Ca:function(){return this[s].L},Sb:function(a,c,d){if(this[s].Ya&&c===this)throw Error("A 'pure' computed must not be called recursively");this[s].s[a]=d;d.Ia=this[s].L++;d.pa=c.Pa()},Sa:function(){var a,c,d=this[s].s;for(a in d)if(d.hasOwnProperty(a)&&(c=d[a],this.oa&&
50
- c.$.Ha||c.$.Zc(c.pa)))return!0},gd:function(){this.oa&&!this[s].Ta&&this.oa(!1)},ca:function(){var a=this[s];return a.V||0<a.L},qd:function(){this.Ha?this[s].V&&(this[s].da=!0):this.ec()},yc:function(a){if(a.gb&&!this[s].i){var c=a.Y(this.gd,this,"dirty"),d=a.Y(this.qd,this);return{$:a,k:function(){c.k();d.k()}}}return a.Y(this.ec,this)},ec:function(){var b=this,c=b.throttleEvaluation;c&&0<=c?(clearTimeout(this[s].fc),this[s].fc=a.a.setTimeout(function(){b.U(!0)},c)):b.oa?b.oa(!0):b.U(!0)},U:function(b){var c=
51
- this[s],d=c.ya,e=!1;if(!c.Ta&&!c.T){if(c.i&&!a.a.qb(c.i)||d&&d()){if(!c.Hb){this.k();return}}else c.Hb=!1;c.Ta=!0;try{e=this.Vc(b)}finally{c.Ta=!1}c.L||this.k();return e}},Vc:function(b){var c=this[s],d=!1,e=c.Ya?n:!c.L,f={Mc:this,Oa:c.s,ob:c.L};a.l.Xb({Lc:f,jb:W,m:this,Va:e});c.s={};c.L=0;f=this.Uc(c,f);this.Ua(c.M,f)&&(c.t||this.notifySubscribers(c.M,"beforeChange"),c.M=f,c.t?this.Kb():b&&this.notifySubscribers(c.M),d=!0);e&&this.notifySubscribers(c.M,"awake");return d},Uc:function(b,c){try{var d=
52
- b.od;return b.sb?d.call(b.sb):d()}finally{a.l.end(),c.ob&&!b.t&&a.a.D(c.Oa,V),b.da=b.V=!1}},p:function(a){var c=this[s];(c.V&&(a||!c.L)||c.t&&this.Sa())&&this.U();return c.M},Wa:function(b){a.K.fn.Wa.call(this,b);this.Mb=function(){this[s].da?this.U():this[s].V=!1;return this[s].M};this.oa=function(a){this.Ob(this[s].M);this[s].V=!0;a&&(this[s].da=!0);this.Pb(this)}},k:function(){var b=this[s];!b.t&&b.s&&a.a.D(b.s,function(a,b){b.k&&b.k()});b.i&&b.pb&&a.a.G.tc(b.i,b.pb);b.s=null;b.L=0;b.T=!0;b.da=
53
- !1;b.V=!1;b.t=!1;b.i=null}},Y={ua:function(b){var c=this,d=c[s];if(!d.T&&d.t&&"change"==b){d.t=!1;if(d.da||c.Sa())d.s=null,d.L=0,c.U()&&c.Kb();else{var e=[];a.a.D(d.s,function(a,b){e[b.Ia]=a});a.a.r(e,function(a,b){var e=d.s[a],l=c.yc(e.$);l.Ia=b;l.pa=e.pa;d.s[a]=l})}d.T||c.notifySubscribers(d.M,"awake")}},Ka:function(b){var c=this[s];c.T||"change"!=b||this.Ra("change")||(a.a.D(c.s,function(a,b){b.k&&(c.s[a]={$:b.$,Ia:b.Ia,pa:b.pa},b.k())}),c.t=!0,this.notifySubscribers(n,"asleep"))},Pa:function(){var b=
54
- this[s];b.t&&(b.da||this.Sa())&&this.U();return a.K.fn.Pa.call(this)}},Z={ua:function(a){"change"!=a&&"beforeChange"!=a||this.p()}};a.a.la&&a.a.$a(z,a.K.fn);var P=a.O.md;a.m[P]=a.O;z[P]=a.m;a.bd=function(b){return a.Qa(b,a.m)};a.cd=function(b){return a.Qa(b,a.m)&&b[s]&&b[s].Ya};a.b("computed",a.m);a.b("dependentObservable",a.m);a.b("isComputed",a.bd);a.b("isPureComputed",a.cd);a.b("computed.fn",z);a.H(z,"peek",z.p);a.H(z,"dispose",z.k);a.H(z,"isActive",z.ca);a.H(z,"getDependenciesCount",z.Ca);a.rc=
55
- function(b,c){if("function"===typeof b)return a.m(b,c,{pure:!0});b=a.a.extend({},b);b.pure=!0;return a.m(b,c)};a.b("pureComputed",a.rc);(function(){function b(a,f,g){g=g||new d;a=f(a);if("object"!=typeof a||null===a||a===n||a instanceof RegExp||a instanceof Date||a instanceof String||a instanceof Number||a instanceof Boolean)return a;var h=a instanceof Array?[]:{};g.save(a,h);c(a,function(c){var d=f(a[c]);switch(typeof d){case "boolean":case "number":case "string":case "function":h[c]=d;break;case "object":case "undefined":var k=
56
- g.get(d);h[c]=k!==n?k:b(d,f,g)}});return h}function c(a,b){if(a instanceof Array){for(var c=0;c<a.length;c++)b(c);"function"==typeof a.toJSON&&b("toJSON")}else for(c in a)b(c)}function d(){this.keys=[];this.Lb=[]}a.Ac=function(c){if(0==arguments.length)throw Error("When calling ko.toJS, pass the object you want to convert.");return b(c,function(b){for(var c=0;a.I(b)&&10>c;c++)b=b();return b})};a.toJSON=function(b,c,d){b=a.Ac(b);return a.a.Gb(b,c,d)};d.prototype={save:function(b,c){var d=a.a.o(this.keys,
57
- b);0<=d?this.Lb[d]=c:(this.keys.push(b),this.Lb.push(c))},get:function(b){b=a.a.o(this.keys,b);return 0<=b?this.Lb[b]:n}}})();a.b("toJS",a.Ac);a.b("toJSON",a.toJSON);(function(){a.j={u:function(b){switch(a.a.A(b)){case "option":return!0===b.__ko__hasDomDataOptionValue__?a.a.e.get(b,a.d.options.zb):7>=a.a.C?b.getAttributeNode("value")&&b.getAttributeNode("value").specified?b.value:b.text:b.value;case "select":return 0<=b.selectedIndex?a.j.u(b.options[b.selectedIndex]):n;default:return b.value}},ja:function(b,
58
- c,d){switch(a.a.A(b)){case "option":switch(typeof c){case "string":a.a.e.set(b,a.d.options.zb,n);"__ko__hasDomDataOptionValue__"in b&&delete b.__ko__hasDomDataOptionValue__;b.value=c;break;default:a.a.e.set(b,a.d.options.zb,c),b.__ko__hasDomDataOptionValue__=!0,b.value="number"===typeof c?c:""}break;case "select":if(""===c||null===c)c=n;for(var e=-1,f=0,g=b.options.length,h;f<g;++f)if(h=a.j.u(b.options[f]),h==c||""==h&&c===n){e=f;break}if(d||0<=e||c===n&&1<b.size)b.selectedIndex=e;break;default:if(null===
59
- c||c===n)c="";b.value=c}}}})();a.b("selectExtensions",a.j);a.b("selectExtensions.readValue",a.j.u);a.b("selectExtensions.writeValue",a.j.ja);a.h=function(){function b(b){b=a.a.cb(b);123===b.charCodeAt(0)&&(b=b.slice(1,-1));var c=[],d=b.match(e),r,h=[],p=0;if(d){d.push(",");for(var A=0,y;y=d[A];++A){var v=y.charCodeAt(0);if(44===v){if(0>=p){c.push(r&&h.length?{key:r,value:h.join("")}:{unknown:r||h.join("")});r=p=0;h=[];continue}}else if(58===v){if(!p&&!r&&1===h.length){r=h.pop();continue}}else 47===
60
- v&&A&&1<y.length?(v=d[A-1].match(f))&&!g[v[0]]&&(b=b.substr(b.indexOf(y)+1),d=b.match(e),d.push(","),A=-1,y="/"):40===v||123===v||91===v?++p:41===v||125===v||93===v?--p:r||h.length||34!==v&&39!==v||(y=y.slice(1,-1));h.push(y)}}return c}var c=["true","false","null","undefined"],d=/^(?:[$_a-z][$\w]*|(.+)(\.\s*[$_a-z][$\w]*|\[.+\]))#x2F;i,e=RegExp("\"(?:[^\"\\\\]|\\\\.)*\"|'(?:[^'\\\\]|\\\\.)*'|/(?:[^/\\\\]|\\\\.)*/w*|[^\\s:,/][^,\"'{}()/:[\\]]*[^\\s,\"'{}()/:[\\]]|[^\\s]","g"),f=/[\])"'A-Za-z0-9_$]+#x2F;,
61
- g={"in":1,"return":1,"typeof":1},h={};return{va:[],ga:h,Ab:b,Xa:function(e,m){function k(b,e){var m;if(!A){var l=a.getBindingHandler(b);if(l&&l.preprocess&&!(e=l.preprocess(e,b,k)))return;if(l=h[b])m=e,0<=a.a.o(c,m)?m=!1:(l=m.match(d),m=null===l?!1:l[1]?"Object("+l[1]+")"+l[2]:m),l=m;l&&g.push("'"+b+"':function(_z){"+m+"=_z}")}p&&(e="function(){return "+e+" }");f.push("'"+b+"':"+e)}m=m||{};var f=[],g=[],p=m.valueAccessors,A=m.bindingParams,y="string"===typeof e?b(e):e;a.a.r(y,function(a){k(a.key||
62
- a.unknown,a.value)});g.length&&k("_ko_property_writers","{"+g.join(",")+" }");return f.join(",")},fd:function(a,b){for(var c=0;c<a.length;c++)if(a[c].key==b)return!0;return!1},Ga:function(b,c,d,e,f){if(b&&a.I(b))!a.Da(b)||f&&b.p()===e||b(e);else if((b=c.get("_ko_property_writers"))&&b[d])b[d](e)}}}();a.b("expressionRewriting",a.h);a.b("expressionRewriting.bindingRewriteValidators",a.h.va);a.b("expressionRewriting.parseObjectLiteral",a.h.Ab);a.b("expressionRewriting.preProcessBindings",a.h.Xa);a.b("expressionRewriting._twoWayBindings",
63
- a.h.ga);a.b("jsonExpressionRewriting",a.h);a.b("jsonExpressionRewriting.insertPropertyAccessorsIntoJson",a.h.Xa);(function(){function b(a){return 8==a.nodeType&&g.test(f?a.text:</