説明なし

um-scripts.js 19KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707
  1. function um_sanitize_value( value, el ) {
  2. var element = document.createElement( 'div' );
  3. element.innerText = value;
  4. var sanitized_value = element.innerHTML;
  5. if ( el ) {
  6. jQuery( el ).val( sanitized_value );
  7. }
  8. return sanitized_value;
  9. }
  10. function um_unsanitize_value( input ) {
  11. var e = document.createElement( 'textarea' );
  12. e.innerHTML = input;
  13. // handle case of empty input
  14. return e.childNodes.length === 0 ? "" : e.childNodes[0].nodeValue;
  15. }
  16. function um_init_datetimepicker() {
  17. jQuery('.um-datepicker:not(.picker__input)').each(function(){
  18. var elem = jQuery(this);
  19. var disable = false;
  20. if ( typeof elem.attr('data-disabled_weekdays') != 'undefined' && elem.attr('data-disabled_weekdays') !== '' ) {
  21. disable = JSON.parse( elem.attr('data-disabled_weekdays') );
  22. }
  23. var years_n = null;
  24. if ( typeof elem.attr('data-years') != 'undefined' ) {
  25. years_n = elem.attr('data-years');
  26. }
  27. var minRange = elem.attr('data-date_min');
  28. var maxRange = elem.attr('data-date_max');
  29. var minSplit = [], maxSplit = [];
  30. if ( typeof minRange != 'undefined' ) {
  31. minSplit = minRange.split(",");
  32. }
  33. if ( typeof maxRange != 'undefined' ) {
  34. maxSplit = maxRange.split(",");
  35. }
  36. var min = minSplit.length ? new Date(minSplit) : null;
  37. var max = minSplit.length ? new Date(maxSplit) : null;
  38. // fix min date for safari
  39. if ( min && min.toString() == 'Invalid Date' && minSplit.length == 3 ) {
  40. var minDateString = minSplit[1] + '/' + minSplit[2] + '/' + minSplit[0];
  41. min = new Date(Date.parse(minDateString));
  42. }
  43. // fix max date for safari
  44. if ( max && max.toString() == 'Invalid Date' && maxSplit.length == 3 ) {
  45. var maxDateString = maxSplit[1] + '/' + maxSplit[2] + '/' + maxSplit[0];
  46. max = new Date(Date.parse(maxDateString));
  47. }
  48. var data = {
  49. disable: disable,
  50. format: elem.attr( 'data-format' ),
  51. formatSubmit: 'yyyy/mm/dd',
  52. hiddenName: true,
  53. onOpen: function() { elem.blur(); },
  54. onClose: function() { elem.blur(); }
  55. };
  56. if ( years_n !== null ) {
  57. data.selectYears = years_n;
  58. }
  59. if ( min !== null ) {
  60. data.min = min;
  61. }
  62. if ( max !== null ) {
  63. data.max = max;
  64. }
  65. elem.pickadate( data );
  66. });
  67. jQuery('.um-timepicker:not(.picker__input)').each(function(){
  68. var elem = jQuery(this);
  69. elem.pickatime({
  70. format: elem.attr('data-format'),
  71. interval: parseInt( elem.attr('data-intervals') ),
  72. formatSubmit: 'HH:i',
  73. hiddenName: true,
  74. onOpen: function() { elem.blur(); },
  75. onClose: function() { elem.blur(); }
  76. });
  77. });
  78. }
  79. function init_tipsy() {
  80. if ( typeof( jQuery.fn.tipsy ) === 'function' ) {
  81. jQuery('.um-tip-n').tipsy({gravity: 'n', opacity: 1, live: 'a.live', offset: 3 });
  82. jQuery('.um-tip-w').tipsy({gravity: 'w', opacity: 1, live: 'a.live', offset: 3 });
  83. jQuery('.um-tip-e').tipsy({gravity: 'e', opacity: 1, live: 'a.live', offset: 3 });
  84. jQuery('.um-tip-s').tipsy({gravity: 's', opacity: 1, live: 'a.live', offset: 3 });
  85. }
  86. }
  87. jQuery(document).ready(function() {
  88. jQuery( document.body ).on('click', '.um-dropdown a.real_url', function() {
  89. window.location = jQuery(this).attr('href');
  90. });
  91. jQuery( document.body ).on( 'click', '.um-trigger-menu-on-click', function() {
  92. var menu = jQuery(this).find('.um-dropdown');
  93. UM.dropdown.show( menu );
  94. return false;
  95. });
  96. jQuery( document.body ).on('click', '.um-dropdown-hide', function() {
  97. UM.dropdown.hideAll();
  98. return false;
  99. });
  100. jQuery( document.body ).on('click', 'a.um-manual-trigger', function() {
  101. var child = jQuery(this).attr('data-child');
  102. var parent = jQuery(this).attr('data-parent');
  103. jQuery(this).parents( parent ).find( child ).trigger('click');
  104. UM.dropdown.hideAll();
  105. return false;
  106. });
  107. jQuery('.um-s1,.um-s2').css({'display':'block'});
  108. /**
  109. * Unselect empty option if something is selected
  110. *
  111. * @since 2.1.16
  112. * @param {object} e
  113. * @returns {undefined}
  114. */
  115. function unselectEmptyOption( e ) {
  116. var $element = jQuery( e.currentTarget );
  117. var $selected = $element.find(':selected');
  118. if ( $selected.length > 1 ) {
  119. $selected.each( function ( i, option ) {
  120. if ( option.value === '' ) {
  121. option.selected = false;
  122. $element.trigger( 'change' );
  123. }
  124. });
  125. }
  126. }
  127. if ( typeof( jQuery.fn.select2 ) === 'function' ) {
  128. jQuery(".um-s1").each( function( e ) {
  129. var obj = jQuery(this);
  130. obj.select2({
  131. allowClear: true,
  132. dropdownParent: obj.parent()
  133. }).on( 'change', unselectEmptyOption );
  134. } );
  135. jQuery(".um-s2").each( function( e ) {
  136. var obj = jQuery(this);
  137. obj.select2({
  138. allowClear: false,
  139. minimumResultsForSearch: 10,
  140. dropdownParent: obj.parent()
  141. }).on( 'change', unselectEmptyOption );
  142. } );
  143. jQuery(".um-s3").each( function( e ) {
  144. var obj = jQuery(this);
  145. obj.select2({
  146. allowClear: false,
  147. minimumResultsForSearch: -1,
  148. dropdownParent: obj.parent()
  149. }).on( 'change', unselectEmptyOption );
  150. } );
  151. }
  152. init_tipsy();
  153. if ( typeof( jQuery.fn.um_raty ) === 'function' ) {
  154. jQuery('.um-rating').um_raty({
  155. half: false,
  156. starType: 'i',
  157. number: function() {
  158. return jQuery(this).attr('data-number');
  159. },
  160. score: function() {
  161. return jQuery(this).attr('data-score');
  162. },
  163. scoreName: function() {
  164. return jQuery(this).attr('data-key');
  165. },
  166. hints: false,
  167. click: function( score, evt ) {
  168. um_live_field = this.id;
  169. um_live_value = score;
  170. um_apply_conditions( jQuery(this), false );
  171. }
  172. });
  173. jQuery('.um-rating-readonly').um_raty({
  174. half: false,
  175. starType: 'i',
  176. number: function() {
  177. return jQuery(this).attr('data-number');
  178. },
  179. score: function() {
  180. return jQuery(this).attr('data-score');
  181. },
  182. scoreName: function() {
  183. return jQuery(this).attr('data-key');
  184. },
  185. hints: false,
  186. readOnly: true
  187. });
  188. }
  189. jQuery(document).on('change', '.um-field-area input[type="radio"]', function() {
  190. var field = jQuery(this).parents('.um-field-area');
  191. var this_field = jQuery(this).parents('label');
  192. field.find('.um-field-radio').removeClass('active');
  193. field.find('.um-field-radio').find('i').removeAttr('class').addClass('um-icon-android-radio-button-off');
  194. this_field.addClass('active');
  195. this_field.find('i').removeAttr('class').addClass('um-icon-android-radio-button-on');
  196. });
  197. jQuery(document).on('change', '.um-field-area input[type="checkbox"]', function() {
  198. var this_field = jQuery(this).parents('label');
  199. if ( this_field.hasClass('active') ) {
  200. this_field.removeClass('active');
  201. this_field.find('i').removeAttr('class').addClass('um-icon-android-checkbox-outline-blank');
  202. } else {
  203. this_field.addClass('active');
  204. this_field.find('i').removeAttr('class').addClass('um-icon-android-checkbox-outline');
  205. }
  206. });
  207. um_init_datetimepicker();
  208. jQuery(document).on('click', '.um .um-single-image-preview a.cancel', function( e ) {
  209. e.preventDefault();
  210. var parent = jQuery(this).parents('.um-field');
  211. var filename = parent.find( 'input[type="hidden"]#' + parent.data('key') + '-' + jQuery(this).parents('form').find('input[type="hidden"][name="form_id"]').val() ).val();
  212. var src = jQuery(this).parents('.um-field').find('.um-single-image-preview img').attr('src');
  213. var mode = parent.data('mode');
  214. var args = {
  215. data: {
  216. mode: mode,
  217. filename: filename,
  218. src: src,
  219. nonce: um_scripts.nonce
  220. },
  221. success: function() {
  222. parent.find('.um-single-image-preview img').attr( 'src', '' );
  223. parent.find('.um-single-image-preview').hide();
  224. parent.find('.um-btn-auto-width').html( parent.data('upload-label') );
  225. parent.find('input[type="hidden"]').val( 'empty_file' );
  226. }
  227. };
  228. if ( mode !== 'register' ) {
  229. args.data.user_id = jQuery(this).parents('form' ).find( '#user_id' ).val();
  230. }
  231. wp.ajax.send( 'um_remove_file', args );
  232. return false;
  233. });
  234. jQuery(document).on('click', '.um .um-single-file-preview a.cancel', function( e ) {
  235. e.preventDefault();
  236. var parent = jQuery(this).parents('.um-field');
  237. var filename = parent.find( 'input[type="hidden"]#' + parent.data('key') + '-' + jQuery(this).parents('form').find('input[type="hidden"][name="form_id"]').val() ).val();
  238. var src = jQuery(this).parents('.um-field').find('.um-single-fileinfo a').attr('href');
  239. var mode = parent.data('mode');
  240. var args = {
  241. data: {
  242. mode: mode,
  243. filename: filename,
  244. src: src,
  245. nonce: um_scripts.nonce
  246. },
  247. success: function() {
  248. parent.find('.um-single-file-preview').hide();
  249. parent.find('.um-btn-auto-width').html( parent.data('upload-label') );
  250. parent.find('input[type=hidden]').val( 'empty_file' );
  251. }
  252. };
  253. if ( mode !== 'register' ) {
  254. args.data.user_id = jQuery(this).parents('form' ).find( '#user_id' ).val();
  255. }
  256. wp.ajax.send( 'um_remove_file', args );
  257. return false;
  258. });
  259. jQuery(document).on('click', '.um-field-group-head:not(.disabled)', function() {
  260. var field = jQuery(this).parents('.um-field-group');
  261. var limit = field.data('max_entries');
  262. if ( field.find('.um-field-group-body').is(':hidden')){
  263. field.find('.um-field-group-body').show();
  264. } else {
  265. field.find('.um-field-group-body:first').clone().appendTo( field );
  266. }
  267. var increase_id = 0;
  268. field.find('.um-field-group-body').each(function(){
  269. increase_id++;
  270. jQuery(this).find('input').each(function(){
  271. var input = jQuery(this);
  272. input.attr('id', input.data('key') + '-' + increase_id );
  273. input.attr('name', input.data('key') + '-' + increase_id );
  274. input.parent().parent().find('label').attr('for', input.data('key') + '-' + increase_id );
  275. });
  276. });
  277. if ( limit > 0 && field.find('.um-field-group-body').length == limit ) {
  278. jQuery(this).addClass('disabled');
  279. }
  280. });
  281. jQuery(document).on('click', '.um-field-group-cancel', function( e ) {
  282. e.preventDefault();
  283. var field = jQuery(this).parents('.um-field-group');
  284. var limit = field.data('max_entries');
  285. if ( field.find('.um-field-group-body').length > 1 ) {
  286. jQuery(this).parents('.um-field-group-body').remove();
  287. } else {
  288. jQuery(this).parents('.um-field-group-body').hide();
  289. }
  290. if ( limit > 0 && field.find('.um-field-group-body').length < limit ) {
  291. field.find('.um-field-group-head').removeClass('disabled');
  292. }
  293. return false;
  294. });
  295. jQuery( document.body ).on( 'click', '.um-ajax-paginate', function( e ) {
  296. e.preventDefault();
  297. var obj = jQuery(this);
  298. var parent = obj.parent();
  299. parent.addClass( 'loading' );
  300. var pages = obj.data('pages')*1;
  301. var next_page = obj.data('page')*1 + 1;
  302. var hook = obj.data('hook');
  303. if ( 'um_load_posts' === hook ) {
  304. jQuery.ajax({
  305. url: wp.ajax.settings.url,
  306. type: 'post',
  307. data: {
  308. action: 'um_ajax_paginate_posts',
  309. author: jQuery(this).data('author'),
  310. page: next_page,
  311. nonce: um_scripts.nonce
  312. },
  313. complete: function() {
  314. parent.removeClass( 'loading' );
  315. },
  316. success: function( data ) {
  317. parent.before( data );
  318. if ( next_page === pages ) {
  319. parent.remove();
  320. } else {
  321. obj.data( 'page', next_page );
  322. }
  323. }
  324. });
  325. } else if ( 'um_load_comments' === hook ) {
  326. jQuery.ajax({
  327. url: wp.ajax.settings.url,
  328. type: 'post',
  329. data: {
  330. action: 'um_ajax_paginate_comments',
  331. user_id: jQuery(this).data('user_id'),
  332. page: next_page,
  333. nonce: um_scripts.nonce
  334. },
  335. complete: function() {
  336. parent.removeClass( 'loading' );
  337. },
  338. success: function( data ) {
  339. parent.before( data );
  340. if ( next_page === pages ) {
  341. parent.remove();
  342. } else {
  343. obj.data( 'page', next_page );
  344. }
  345. }
  346. });
  347. } else {
  348. var args = jQuery(this).data('args');
  349. var container = jQuery(this).parents('.um').find('.um-ajax-items');
  350. jQuery.ajax({
  351. url: wp.ajax.settings.url,
  352. type: 'post',
  353. data: {
  354. action: 'um_ajax_paginate',
  355. hook: hook,
  356. args: args,
  357. nonce: um_scripts.nonce
  358. },
  359. complete: function() {
  360. parent.removeClass( 'loading' );
  361. },
  362. success: function(data){
  363. parent.remove();
  364. container.append( data );
  365. }
  366. });
  367. }
  368. });
  369. jQuery(document).on('click', '.um-ajax-action', function( e ) {
  370. e.preventDefault();
  371. var hook = jQuery(this).data('hook');
  372. var user_id = jQuery(this).data('user_id');
  373. var arguments = jQuery(this).data('arguments');
  374. if ( jQuery(this).data('js-remove') ){
  375. jQuery(this).parents('.'+jQuery(this).data('js-remove')).fadeOut('fast');
  376. }
  377. jQuery.ajax({
  378. url: wp.ajax.settings.url,
  379. type: 'post',
  380. data: {
  381. action: 'um_muted_action',
  382. hook: hook,
  383. user_id: user_id,
  384. arguments: arguments,
  385. nonce: um_scripts.nonce
  386. },
  387. success: function(data){
  388. }
  389. });
  390. return false;
  391. });
  392. jQuery( document.body ).on('click', '#um-search-button', function() {
  393. var action = jQuery(this).parents('.um-search-form').data('members_page');
  394. var search_keys = [];
  395. jQuery(this).parents('.um-search-form').find('input[name="um-search-keys[]"]').each( function() {
  396. search_keys.push( jQuery(this).val() );
  397. });
  398. var search = jQuery(this).parents('.um-search-form').find('.um-search-field').val();
  399. var url;
  400. if ( search === '' ) {
  401. url = action;
  402. } else {
  403. var query = '?';
  404. for ( var i = 0; i < search_keys.length; i++ ) {
  405. query += search_keys[i] + '=' + search;
  406. if ( i !== search_keys.length - 1 ) {
  407. query += '&';
  408. }
  409. }
  410. url = action + query;
  411. }
  412. window.location = url;
  413. });
  414. //make search on Enter click
  415. jQuery( document.body ).on( 'keypress', '.um-search-field', function(e) {
  416. if ( e.which === 13 ) {
  417. var action = jQuery(this).parents('.um-search-form').data('members_page');
  418. var search_keys = [];
  419. jQuery(this).parents('.um-search-form').find('input[name="um-search-keys[]"]').each( function() {
  420. search_keys.push( jQuery(this).val() );
  421. });
  422. var search = jQuery(this).val();
  423. var url;
  424. if ( search === '' ) {
  425. url = action;
  426. } else {
  427. var query = '?';
  428. for ( var i = 0; i < search_keys.length; i++ ) {
  429. query += search_keys[i] + '=' + search;
  430. if ( i !== search_keys.length - 1 ) {
  431. query += '&';
  432. }
  433. }
  434. url = action + query;
  435. }
  436. window.location = url;
  437. }
  438. });
  439. jQuery('.um-form input[class="um-button"][type="submit"]').prop('disabled', false);
  440. jQuery(document).one('click', '.um:not(.um-account) .um-form input[class="um-button"][type="submit"]:not(.um-has-recaptcha)', function() {
  441. jQuery(this).attr('disabled','disabled');
  442. jQuery(this).parents('form').trigger('submit');
  443. });
  444. var um_select_options_cache = {};
  445. /**
  446. * Find all select fields with parent select fields
  447. */
  448. jQuery('select[data-um-parent]').each( function() {
  449. var me = jQuery(this);
  450. var parent_option = me.data('um-parent');
  451. var um_ajax_source = me.data('um-ajax-source');
  452. me.attr('data-um-init-field', true );
  453. jQuery(document).on('change','select[name="' + parent_option + '"]',function() {
  454. var parent = jQuery(this);
  455. var form_id = parent.closest( 'form' ).find( 'input[type="hidden"][name="form_id"]' ).val();
  456. var arr_key;
  457. if ( me.attr( 'data-member-directory' ) === 'yes' ) {
  458. var directory = parent.parents('.um-directory');
  459. arr_key = um_get_data_for_directory( directory, 'filter_' + parent_option );
  460. if ( typeof arr_key != 'undefined' ) {
  461. arr_key = arr_key.split('||');
  462. } else {
  463. arr_key = '';
  464. }
  465. } else {
  466. arr_key = parent.val();
  467. }
  468. if ( typeof arr_key != 'undefined' && arr_key !== '' && typeof um_select_options_cache[ arr_key ] !== 'object' ) {
  469. if ( typeof( me.um_wait ) === 'undefined' || me.um_wait === false ) {
  470. me.um_wait = true;
  471. } else {
  472. return;
  473. }
  474. jQuery.ajax({
  475. url: wp.ajax.settings.url,
  476. type: 'post',
  477. data: {
  478. action: 'um_select_options',
  479. parent_option_name: parent_option,
  480. parent_option: arr_key,
  481. child_callback: um_ajax_source,
  482. child_name: me.attr('name'),
  483. members_directory: me.attr('data-member-directory'),
  484. form_id: form_id,
  485. nonce: um_scripts.nonce
  486. },
  487. success: function( data ) {
  488. if ( data.status === 'success' && arr_key !== '' ) {
  489. um_select_options_cache[ arr_key ] = data;
  490. um_field_populate_child_options( me, data, arr_key );
  491. }
  492. if ( typeof data.debug !== 'undefined' ) {
  493. console.log( data );
  494. }
  495. me.um_wait = false;
  496. },
  497. error: function( e ) {
  498. console.log( e );
  499. me.um_wait = false;
  500. }
  501. });
  502. }
  503. if ( typeof arr_key != 'undefined' && arr_key !== '' && typeof um_select_options_cache[ arr_key ] == 'object' ) {
  504. setTimeout( um_field_populate_child_options, 10, me, um_select_options_cache[ arr_key ], arr_key );
  505. }
  506. if ( typeof arr_key != 'undefined' || arr_key === '' ) {
  507. me.find('option[value!=""]').remove();
  508. me.val('').trigger('change');
  509. }
  510. });
  511. jQuery('select[name="' + parent_option + '"]').trigger('change');
  512. });
  513. /**
  514. * Populates child options and cache ajax response
  515. *
  516. * @param me
  517. * @param data
  518. * @param arr_key
  519. */
  520. function um_field_populate_child_options( me, data, arr_key ) {
  521. var directory = me.parents('.um-directory');
  522. var child_name = me.attr('name');
  523. me.find('option[value!=""]').remove();
  524. if ( ! me.hasClass('um-child-option-disabled') ) {
  525. me.prop('disabled', false);
  526. }
  527. var arr_items = [],
  528. search_get = '';
  529. if ( data.post.members_directory === 'yes' ) {
  530. arr_items.push({id: '', text: '', selected: 1});
  531. }
  532. jQuery.each( data.items, function(k,v){
  533. arr_items.push({id: k, text: v, selected: (v === search_get)});
  534. });
  535. me.select2('destroy');
  536. me.select2({
  537. data: arr_items,
  538. allowClear: true,
  539. minimumResultsForSearch: 10
  540. });
  541. if ( data.post.members_directory === 'yes' ) {
  542. me.find('option').each( function() {
  543. if ( jQuery(this).html() !== '' ) {
  544. jQuery(this).data( 'value_label', jQuery(this).html() ).attr( 'data-value_label', jQuery(this).html() );
  545. }
  546. });
  547. var current_filter_val = um_get_data_for_directory( directory, 'filter_' + child_name );
  548. if ( typeof current_filter_val !== 'undefined' ) {
  549. current_filter_val = current_filter_val.split('||');
  550. var temp_filter_val = [];
  551. jQuery.each( current_filter_val, function(i) {
  552. if ( me.find('option[value="' + current_filter_val[ i ] + '"]').length ) {
  553. temp_filter_val.push( current_filter_val[ i ] );
  554. }
  555. me.find('option[value="' + current_filter_val[ i ] + '"]').prop('disabled', true).hide();
  556. if ( me.find('option:not(:disabled)').length === 1 ) {
  557. me.prop('disabled', true);
  558. }
  559. me.select2('destroy').select2();
  560. me.val('').trigger( 'change' );
  561. });
  562. temp_filter_val = temp_filter_val.join('||');
  563. if ( current_filter_val !== temp_filter_val ) {
  564. um_set_url_from_data( directory, 'filter_' + child_name, temp_filter_val );
  565. um_ajax_get_members( directory );
  566. }
  567. }
  568. um_change_tag( directory );
  569. }
  570. if ( data.post.members_directory !== 'yes' ) {
  571. if ( typeof data.field.default !== 'undefined' && ! me.data('um-original-value') ) {
  572. me.val( data.field.default ).trigger('change');
  573. } else if ( me.data('um-original-value') !== '' ) {
  574. me.val( me.data('um-original-value') ).trigger('change');
  575. }
  576. if ( data.field.editable == 0 ) {
  577. me.addClass('um-child-option-disabled');
  578. me.attr('disabled','disabled');
  579. }
  580. }
  581. }
  582. });