Lingotek Translation - Version 1.3.0

Version Description

(2017-7-10) =

  • Added the Lingotek Professional Translation workflow.
  • Fixed a bug that was showing the incorrect profile type.
Download this release

Release Info

Developer robertdhanna
Plugin Icon 128x128 Lingotek Translation
Version 1.3.0
Comparing to
See all releases

Code changes from version 1.2.9 to 1.3.0

Files changed (54) hide show
  1. admin/actions.php +77 -4
  2. admin/admin.php +3 -2
  3. admin/filters-columns.php +29 -13
  4. admin/filters-post.php +9 -9
  5. admin/filters-term.php +6 -0
  6. admin/post-actions.php +6 -1
  7. admin/settings/view-account.php +40 -0
  8. admin/strings-table.php +19 -7
  9. admin/workflows/credit-card-to-path.php +48 -0
  10. admin/workflows/professional-translation-workflow.php +475 -58
  11. admin/workflows/workflow-factory.php +9 -4
  12. admin/workflows/workflow.php +232 -45
  13. css/workflow/professional-workflow-style.css +1015 -0
  14. error.log +0 -0
  15. img/blue-radio-button.svg +15 -0
  16. img/checkmark-green.svg +18 -0
  17. img/credit-cards/alipay.svg +11 -0
  18. img/credit-cards/amex.svg +14 -0
  19. img/credit-cards/default.svg +14 -0
  20. img/credit-cards/diners.svg +15 -0
  21. img/credit-cards/discover.svg +7 -0
  22. img/credit-cards/hipercard.svg +7 -0
  23. img/credit-cards/jcb.svg +29 -0
  24. img/credit-cards/maestro.svg +29 -0
  25. img/credit-cards/mastercard.svg +34 -0
  26. img/credit-cards/paypal.svg +52 -0
  27. img/credit-cards/unionpay.svg +13 -0
  28. img/credit-cards/visa.svg +17 -0
  29. img/credit-dots.svg +31 -0
  30. img/error.svg +15 -0
  31. img/human-translation.svg +18 -0
  32. img/lingotek-logo-white.png +0 -0
  33. img/loading.gif +0 -0
  34. img/loading_mini.gif +0 -0
  35. img/minimum-help.svg +20 -0
  36. img/minimum-warning.svg +21 -0
  37. img/questionmark.svg +14 -0
  38. img/right-arrow.svg +16 -0
  39. img/translation-logo.png +0 -0
  40. include/api.php +131 -1
  41. include/group-post.php +4 -6
  42. include/group-string.php +1 -1
  43. include/group-term.php +1 -1
  44. include/group.php +210 -42
  45. include/http.php +2 -2
  46. include/model.php +19 -2
  47. js/updater.js +16 -4
  48. js/workflow/professional-workflow-account.js +62 -0
  49. js/workflow/professional-workflow-defaults.js +160 -0
  50. js/workflow/professional-workflow.js +1849 -17
  51. js/workflow/workflow-defaults.js +0 -19
  52. js/workflow/workflow.js +69 -2
  53. lingotek.php +287 -20
  54. readme.txt +7 -2
admin/actions.php CHANGED
@@ -145,6 +145,11 @@ abstract class Lingotek_Actions {
145
 
146
  add_action( 'admin_enqueue_scripts', array( &$this, 'admin_enqueue_scripts' ) );
147
 
 
 
 
 
 
148
  foreach ( array_keys( self::$actions ) as $action ) {
149
  add_action( 'wp_ajax_lingotek_progress_' . $this->type . '_' . $action , array( &$this, 'ajax_' . $action ) );
150
  }
@@ -222,8 +227,8 @@ abstract class Lingotek_Actions {
222
  */
223
  public static function display_icon( $name, $link, $additional = '' ) {
224
  self::link_to_settings_if_not_connected($link);
225
- return sprintf('<a class="lingotek-color dashicons dashicons-%s" title="%s" href="%s"%s></a>',
226
- self::$icons[ $name ]['icon'], self::$icons[ $name ]['title'], esc_url( $link ), $additional);
227
  }
228
 
229
  /**
@@ -298,14 +303,16 @@ abstract class Lingotek_Actions {
298
  return self::display_icon( $document->translations[ $language->locale ], $link );
299
  } elseif ( 'not-current' === $document->translations[ $language->locale ] ) {
300
  return '<div class="lingotek-color dashicons dashicons-no"></div>';
 
 
301
  } else {
302
- self::link_to_settings_if_not_connected($link);
303
  $link = self::workbench_link( $document->document_id, $language->lingotek_locale );
 
304
  return self::display_icon( $document->translations[ $language->locale ], $link, ' target="_blank"' );
305
  }
306
  } else {
 
307
  self::link_to_settings_if_not_connected($link);
308
- $link = wp_nonce_url( add_query_arg( array( 'document_id' => $document->document_id, 'locale' => $language->locale, 'action' => 'lingotek-request', 'noheader' => true ) ), 'lingotek-request' );
309
  return self::display_icon( 'request', $link );
310
  }
311
  }
@@ -371,6 +378,18 @@ abstract class Lingotek_Actions {
371
  } else {
372
  $actions['lingotek-upload'] = $this->get_action_link( array( $this->type => $id, 'action' => 'upload' ) );
373
  }
 
 
 
 
 
 
 
 
 
 
 
 
374
  } else {
375
  $actions['lingotek-upload'] = $this->get_action_link( array( $this->type => $id, 'action' => 'upload' ) );
376
  }
@@ -570,6 +589,60 @@ abstract class Lingotek_Actions {
570
  die();
571
  }
572
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
573
  /**
574
  * Collects and returns all API errors
575
  *
145
 
146
  add_action( 'admin_enqueue_scripts', array( &$this, 'admin_enqueue_scripts' ) );
147
 
148
+ add_action( 'wp_ajax_estimate_cost', array( &$this, 'ajax_estimate_cost' ) );
149
+ add_action( 'wp_ajax_request_professional_translation', array( &$this, 'ajax_request_professional_translation' ) );
150
+ add_action( 'wp_ajax_get_user_payment_information', array( &$this, 'ajax_get_user_payment_information' ) );
151
+ add_action( 'wp_ajax_get_ltk_terms_and_conditions', array( &$this, 'ajax_get_ltk_terms_and_conditions' ) );
152
+
153
  foreach ( array_keys( self::$actions ) as $action ) {
154
  add_action( 'wp_ajax_lingotek_progress_' . $this->type . '_' . $action , array( &$this, 'ajax_' . $action ) );
155
  }
227
  */
228
  public static function display_icon( $name, $link, $additional = '' ) {
229
  self::link_to_settings_if_not_connected($link);
230
+ return sprintf('<a class="lingotek-color dashicons dashicons-%s dashicons-%s-lingotek" title="%s" href="%s"%s></a>',
231
+ self::$icons[ $name ]['icon'], self::$icons[ $name ]['icon'], self::$icons[ $name ]['title'], esc_url( $link ), $additional);
232
  }
233
 
234
  /**
303
  return self::display_icon( $document->translations[ $language->locale ], $link );
304
  } elseif ( 'not-current' === $document->translations[ $language->locale ] ) {
305
  return '<div class="lingotek-color dashicons dashicons-no"></div>';
306
+ } elseif ('current' !== $document->translations[ $language->locale ] && $custom_icon = $document->get_custom_in_progress_icon($language)) {
307
+ return $custom_icon;
308
  } else {
 
309
  $link = self::workbench_link( $document->document_id, $language->lingotek_locale );
310
+ self::link_to_settings_if_not_connected($link);
311
  return self::display_icon( $document->translations[ $language->locale ], $link, ' target="_blank"' );
312
  }
313
  } else {
314
+ $link = wp_nonce_url( add_query_arg( array( 'document_id' => $document->document_id, 'locale' => $language->locale, 'action' => 'lingotek-request', 'noheader' => true ), wp_get_referer() ), 'lingotek-request' );
315
  self::link_to_settings_if_not_connected($link);
 
316
  return self::display_icon( 'request', $link );
317
  }
318
  }
378
  } else {
379
  $actions['lingotek-upload'] = $this->get_action_link( array( $this->type => $id, 'action' => 'upload' ) );
380
  }
381
+
382
+ /**
383
+ * If a document has been changed but still has translations or is importing we still want to have the
384
+ * update translation status option.
385
+ */
386
+ if ( 'importing' === $document->status || $document->has_translation_status( 'pending' ) ) {
387
+ $actions['lingotek-status'] = $this->get_action_link( array( 'document_id' => $document->document_id, 'action' => 'status' ) );
388
+ }
389
+
390
+ if ( $document->has_translation_status( 'ready' ) ) {
391
+ $actions['lingotek-download'] = $this->get_action_link( array( 'document_id' => $document->document_id, 'action' => 'download' ) );
392
+ }
393
  } else {
394
  $actions['lingotek-upload'] = $this->get_action_link( array( $this->type => $id, 'action' => 'upload' ) );
395
  }
589
  die();
590
  }
591
 
592
+ /**
593
+ * Ajax call to get the price estimation of a given document.
594
+ */
595
+ public function ajax_estimate_cost() {
596
+ check_ajax_referer( 'lingotek_professional', '_lingotek_nonce' );
597
+ $document_id = filter_input( INPUT_GET, 'document_id' );
598
+ $locale = filter_input( INPUT_GET, 'locale' );
599
+ $lingotek_auth = filter_input( INPUT_GET, 'Authorization-Lingotek' );
600
+ $client = new Lingotek_API();
601
+ $response = $client->get_cost_estimate($lingotek_auth, $document_id, $locale);
602
+ echo json_encode($response);
603
+ die();
604
+ }
605
+
606
+ /**
607
+ * Ajax call to request professional translation of a document through bridge.
608
+ */
609
+ public function ajax_request_professional_translation() {
610
+ check_ajax_referer( 'lingotek_professional', '_lingotek_nonce' );
611
+ $post_vars = filter_input_array(INPUT_POST);
612
+ $client = new Lingotek_API();
613
+ $response = $client->request_professional_translation_bulk($post_vars['workflow_id'], $post_vars['translations'], $post_vars['total_estimate'], $post_vars['summary']);
614
+ if (true === $response['data']['transaction_approved']) {
615
+ foreach ($post_vars['translations'] as $document_id => $locales) {
616
+ if ( $document = $this->lgtm->get_group( $post_vars['type'], $post_vars['ids'][$document_id] ) ) {
617
+ foreach ($locales as $locale) {
618
+ $locale = $post_vars['lingotek_locale_to_wp_locale'][$locale];
619
+ $document->update_translation_status($locale, 'pending');
620
+ }
621
+ } else {
622
+ // TODO: what if a document doesn't exists? T_T
623
+ }
624
+ }
625
+ }
626
+
627
+ echo json_encode($response);
628
+ die();
629
+ }
630
+
631
+ public function ajax_get_ltk_terms_and_conditions() {
632
+ check_ajax_referer( 'lingotek_professional', '_lingotek_nonce' );
633
+ $client = new Lingotek_API();
634
+ echo json_encode($client->get_lingotek_terms_and_conditions());
635
+ die();
636
+ }
637
+
638
+ public function ajax_get_user_payment_information() {
639
+ check_ajax_referer( 'lingotek_professional', '_lingotek_nonce' );
640
+ $client = new Lingotek_API();
641
+ $response = $client->get_user_payment_information();
642
+ echo json_encode($response);
643
+ die();
644
+ }
645
+
646
  /**
647
  * Collects and returns all API errors
648
  *
admin/admin.php CHANGED
@@ -348,7 +348,6 @@ class Lingotek_Admin {
348
  * and launches a modal when one of them is selected in the default list.
349
  */
350
  Lingotek_Workflow_Factory::echo_info_modals();
351
- wp_enqueue_script( 'lingotek_workflow_defaults', LINGOTEK_URL . '/js/workflow/workflow-defaults.js' );
352
 
353
  $resources = get_option( 'lingotek_community_resources' );
354
  $options = array(
@@ -482,9 +481,11 @@ class Lingotek_Admin {
482
  if ( empty( $diff ) ) {
483
  $workflows = array(
484
  'c675bd20-0688-11e2-892e-0800200c9a66' => 'Machine Translation',
485
- // 'professional-translation' => 'Professional Translation',
486
  );
487
  }
 
 
 
488
  natcasesort( $workflows ); // order by title (case-insensitive).
489
  $refresh_success['workflows'] = true;
490
  }
348
  * and launches a modal when one of them is selected in the default list.
349
  */
350
  Lingotek_Workflow_Factory::echo_info_modals();
 
351
 
352
  $resources = get_option( 'lingotek_community_resources' );
353
  $options = array(
481
  if ( empty( $diff ) ) {
482
  $workflows = array(
483
  'c675bd20-0688-11e2-892e-0800200c9a66' => 'Machine Translation',
 
484
  );
485
  }
486
+ if (Lingotek_Professional_Translation_Workflow::is_allowed_user()) {
487
+ $workflows['ab6c522a-7645-4317-9284-3fbddf516151'] = 'Lingotek Professional Translation';
488
+ }
489
  natcasesort( $workflows ); // order by title (case-insensitive).
490
  $refresh_success['workflows'] = true;
491
  }
admin/filters-columns.php CHANGED
@@ -113,8 +113,9 @@ class Lingotek_Filters_Columns extends PLL_Admin_Filters_Columns {
113
  $actions = 'post' === $type ? $GLOBALS['wp_lingotek']->post_actions : $GLOBALS['wp_lingotek']->term_actions;
114
 
115
  $profile = Lingotek_Model::get_profile( $this->content_type, $language, $object_id );
116
- $disabled = 'disabled' === $profile['profile'];
117
-
 
118
  // post ready for upload.
119
  if ( $this->lgtm->can_upload( $type, $object_id ) && $object_id === $id ) {
120
  return $disabled ? ('post' === $type ? parent::post_column( $column, $object_id ) : parent::term_column( '', $column, $object_id ))
@@ -131,7 +132,7 @@ class Lingotek_Filters_Columns extends PLL_Admin_Filters_Columns {
131
  }
132
  }
133
  } // translation disabled.
134
- elseif ( isset( $document->source ) && $document->is_disabled_target( $source_language, $language ) && ! isset( $document->translations[ $language->locale ] ) ) {
135
  return 'post' === $type ? parent::post_column( $column, $object_id ) : parent::term_column( '', $column, $object_id );
136
  } // source post is uploaded.
137
  elseif ( isset( $document->source ) && $document->source === $id ) {
@@ -150,7 +151,7 @@ class Lingotek_Filters_Columns extends PLL_Admin_Filters_Columns {
150
  } // translations.
151
  elseif ( isset( $document->translations[ $language->locale ] ) || (isset( $document->source ) && 'current' === $document->status) ) {
152
  return Lingotek_Actions::translation_icon( $document, $language );
153
- } elseif ( 'term' === $type && ! isset( $document->translations[ $language->locale ] ) && $document->source !== $object_id ) {
154
  return parent::term_column( '', $column, $object_id );
155
  } // translations exist but are not managed by Lingotek TMS.
156
  elseif ( empty( $document->source ) ) {
@@ -181,8 +182,12 @@ class Lingotek_Filters_Columns extends PLL_Admin_Filters_Columns {
181
  'target' => array()
182
  ),
183
  'div' => array(
 
184
  'class' => array(),
185
  ),
 
 
 
186
  );
187
  echo wp_kses( $this->_column( 'post', $column, $post_id ), $allowed_html );
188
 
@@ -190,11 +195,14 @@ class Lingotek_Filters_Columns extends PLL_Admin_Filters_Columns {
190
  * Setup workflow specific logic for posts.
191
  */
192
  $post = get_post( $post_id );
193
- $language = PLL()->model->post->get_language( $post_id );
194
- $workflow_id = Lingotek_Model::get_profile_option( 'workflow_id', $post->post_type, $language, false, $post_id );
195
- $workflow = Lingotek_Workflow_Factory::get_workflow_instance( $workflow_id ); // TODO: put workflow_id here. It is currently not set up.
196
- $workflow->override_events( $workflow_id ); // Loads appropriate .js file.
197
- $workflow->echo_posts_modal( $workflow_id ); // adds modal html to page.
 
 
 
198
 
199
  // checking for api errors.
200
  $document = $this->lgtm->get_group( 'post', $post_id );
@@ -225,21 +233,29 @@ class Lingotek_Filters_Columns extends PLL_Admin_Filters_Columns {
225
  'target' => array()
226
  ),
227
  'div' => array(
 
228
  'class' => array(),
229
  ),
230
  'span' => array(
231
  'class' => array(),
232
  ),
 
 
 
233
  );
234
  $this->content_type = $GLOBALS['taxonomy'];
235
 
236
  /**
237
  * Setup workflow specific logic for terms.
238
  */
239
- $workflow_id = Lingotek_Model::get_profile_option( 'workflow_id', $this->content_type, PLL()->model->term->get_language( $term_id ) );
240
- $workflow = Lingotek_Workflow_Factory::get_workflow_instance( $workflow_id ); // TODO: put workflow_id here. It is currently not set up.
241
- $workflow->override_events( $workflow_id ); // Loads appropriate .js file.
242
- $workflow->echo_terms_modal( $workflow_id ); // adds modal html to page.
 
 
 
 
243
 
244
  if ( ! $custom_data ) {
245
  echo wp_kses( $this->_column( 'term', $column, $term_id ), $allowed_html );
113
  $actions = 'post' === $type ? $GLOBALS['wp_lingotek']->post_actions : $GLOBALS['wp_lingotek']->term_actions;
114
 
115
  $profile = Lingotek_Model::get_profile( $this->content_type, $language, $object_id );
116
+
117
+ $disabled = 'disabled' === $profile['profile'] || !Lingotek::is_allowed_tms_locale($language->lingotek_locale);
118
+ // error_log('bool: ' . print_r($disabled, true) . PHP_EOL, 3, '/var/www/html/wp-content/plugins/lingotek-translation/error.log');
119
  // post ready for upload.
120
  if ( $this->lgtm->can_upload( $type, $object_id ) && $object_id === $id ) {
121
  return $disabled ? ('post' === $type ? parent::post_column( $column, $object_id ) : parent::term_column( '', $column, $object_id ))
132
  }
133
  }
134
  } // translation disabled.
135
+ elseif ( ( isset( $document->source ) && $document->is_disabled_target( $source_language, $language ) && ! isset( $document->translations[ $language->locale ] ) ) || !Lingotek::is_allowed_tms_locale($language->lingotek_locale) ) {
136
  return 'post' === $type ? parent::post_column( $column, $object_id ) : parent::term_column( '', $column, $object_id );
137
  } // source post is uploaded.
138
  elseif ( isset( $document->source ) && $document->source === $id ) {
151
  } // translations.
152
  elseif ( isset( $document->translations[ $language->locale ] ) || (isset( $document->source ) && 'current' === $document->status) ) {
153
  return Lingotek_Actions::translation_icon( $document, $language );
154
+ } elseif ( ( 'term' === $type && ! isset( $document->translations[ $language->locale ] ) && $document->source !== $object_id ) || !Lingotek::is_allowed_tms_locale($language->lingotek_locale) ) {
155
  return parent::term_column( '', $column, $object_id );
156
  } // translations exist but are not managed by Lingotek TMS.
157
  elseif ( empty( $document->source ) ) {
182
  'target' => array()
183
  ),
184
  'div' => array(
185
+ 'title' => array(),
186
  'class' => array(),
187
  ),
188
+ 'img' => array(
189
+ 'src' => array()
190
+ )
191
  );
192
  echo wp_kses( $this->_column( 'post', $column, $post_id ), $allowed_html );
193
 
195
  * Setup workflow specific logic for posts.
196
  */
197
  $post = get_post( $post_id );
198
+ $source_language = PLL()->model->post->get_language( $post_id );
199
+ $target_language = $this->model->get_language( substr( $column, 9 ) );
200
+ if (is_object($source_language) && is_object($target_language)) {
201
+ $workflow_id = Lingotek_Model::get_profile_option( 'workflow_id', $post->post_type, $source_language, $target_language, $post_id );
202
+ $workflow = Lingotek_Workflow_Factory::get_workflow_instance( $workflow_id );
203
+ // $workflow->override_events( $workflow_id ); // Loads appropriate .js file.
204
+ $workflow->echo_posts_modal( $post_id, $target_language->locale ); // adds modal html to page.
205
+ }
206
 
207
  // checking for api errors.
208
  $document = $this->lgtm->get_group( 'post', $post_id );
233
  'target' => array()
234
  ),
235
  'div' => array(
236
+ 'title' => array(),
237
  'class' => array(),
238
  ),
239
  'span' => array(
240
  'class' => array(),
241
  ),
242
+ 'img' => array(
243
+ 'src' => array()
244
+ )
245
  );
246
  $this->content_type = $GLOBALS['taxonomy'];
247
 
248
  /**
249
  * Setup workflow specific logic for terms.
250
  */
251
+ $source_language = PLL()->model->term->get_language( $term_id );
252
+ $target_language = $this->model->get_language( substr( $column, 9 ) );
253
+ if (is_object($source_language) && is_object($target_language)) {
254
+ $workflow_id = Lingotek_Model::get_profile_option( 'workflow_id', $this->content_type, $source_language, $target_language );
255
+ $workflow = Lingotek_Workflow_Factory::get_workflow_instance( $workflow_id );
256
+ // $workflow->override_events( $workflow_id ); // Loads appropriate .js file.
257
+ $workflow->echo_terms_modal( $term_id, $target_language->locale); // adds modal html to page.
258
+ }
259
 
260
  if ( ! $custom_data ) {
261
  echo wp_kses( $this->_column( 'term', $column, $term_id ), $allowed_html );
admin/filters-post.php CHANGED
@@ -99,7 +99,7 @@ class Lingotek_Filters_Post extends PLL_Admin_Filters_Post {
99
  $profile = $content_profiles[$post_type]['sources'][$post_language->slug];
100
  echo $profiles[$profile]['name'];
101
  }
102
- else if (!empty($content_profiles) && !isset($profiles[$content_profiles[$post_type]['profile']]['name']))
103
  {
104
  echo esc_html( __('Disabled', 'lingotek-translation') );
105
  }
@@ -107,12 +107,7 @@ class Lingotek_Filters_Post extends PLL_Admin_Filters_Post {
107
  echo $profiles[$content_profiles[$post_type]['profile']]['name'];
108
  }
109
  else {
110
- if ($post_type == 'post') {
111
- _e('Automatic', 'lingotek-translation');
112
- }
113
- else if ($post_type == 'page') {
114
- _e('Manual', 'lingotek-translation');
115
- }
116
  }
117
  }
118
  }
@@ -138,8 +133,13 @@ class Lingotek_Filters_Post extends PLL_Admin_Filters_Post {
138
  * @param bool $update whether it is an update or not
139
  */
140
  public function save_post($post_id, $post, $update) {
 
 
 
 
 
 
141
  if ($this->can_save_post_data($post_id, $post, true)) {
142
- $document = $this->lgtm->get_group('post', $post_id);
143
  // updated post
144
  if ($document && $post_id == $document->source && $this->post_hash_has_changed($post)) {
145
  $document->source_edited();
@@ -154,7 +154,7 @@ class Lingotek_Filters_Post extends PLL_Admin_Filters_Post {
154
  // new post
155
  if (!isset($_REQUEST['import'])) {
156
  parent::save_post($post_id, $post, $update);
157
- if (!wp_is_post_revision($post_id) && 'auto-draft' != $post->post_status && 'automatic' == Lingotek_Model::get_profile_option('upload', $post->post_type, PLL()->model->post->get_language($post_id), false, $post_id) && Lingotek_Group_Post::is_valid_auto_upload_post_status($post->post_status) && !(isset($_POST['action']) && 'heartbeat' == $_POST['action']) && $this->lgtm->can_upload('post', $post_id)) {
158
  $this->lgtm->upload_post($post_id);
159
  }
160
  }
99
  $profile = $content_profiles[$post_type]['sources'][$post_language->slug];
100
  echo $profiles[$profile]['name'];
101
  }
102
+ else if (!empty($content_profiles) && !isset($content_profiles[$post_type]) && !isset($profiles[$content_profiles[$post_type]['profile']]['name']))
103
  {
104
  echo esc_html( __('Disabled', 'lingotek-translation') );
105
  }
107
  echo $profiles[$content_profiles[$post_type]['profile']]['name'];
108
  }
109
  else {
110
+ _e('Manual', 'lingotek-translation');
 
 
 
 
 
111
  }
112
  }
113
  }
133
  * @param bool $update whether it is an update or not
134
  */
135
  public function save_post($post_id, $post, $update) {
136
+
137
+ $document = $this->lgtm->get_group('post', $post_id);
138
+ if ($document) {
139
+ $language = PLL()->model->post->get_language($post_id);
140
+ $document->pre_save_post($post_id, 'post', $language);
141
+ }
142
  if ($this->can_save_post_data($post_id, $post, true)) {
 
143
  // updated post
144
  if ($document && $post_id == $document->source && $this->post_hash_has_changed($post)) {
145
  $document->source_edited();
154
  // new post
155
  if (!isset($_REQUEST['import'])) {
156
  parent::save_post($post_id, $post, $update);
157
+ if (!$document && !wp_is_post_revision($post_id) && 'auto-draft' != $post->post_status && 'automatic' == Lingotek_Model::get_profile_option('upload', $post->post_type, PLL()->model->post->get_language($post_id), false, $post_id) && Lingotek_Group_Post::is_valid_auto_upload_post_status($post->post_status) && !(isset($_POST['action']) && 'heartbeat' == $_POST['action']) && $this->lgtm->can_upload('post', $post_id)) {
158
  $this->lgtm->upload_post($post_id);
159
  }
160
  }
admin/filters-term.php CHANGED
@@ -60,6 +60,12 @@ class Lingotek_Filters_Term extends PLL_Admin_Filters_Term {
60
  * @param string $taxonomy taxonomy.
61
  */
62
  public function save_term( $term_id, $tt_id, $taxonomy ) {
 
 
 
 
 
 
63
  if ( ! $this->model->is_translated_taxonomy( $taxonomy ) ) {
64
  return;
65
  }
60
  * @param string $taxonomy taxonomy.
61
  */
62
  public function save_term( $term_id, $tt_id, $taxonomy ) {
63
+ $document = $this->lgtm->get_group('term', $term_id);
64
+ if ($document) {
65
+ $document->pre_save_terms($term_id, $taxonomy, PLL()->model->term->get_language( $term_id ));
66
+ }
67
+
68
+
69
  if ( ! $this->model->is_translated_taxonomy( $taxonomy ) ) {
70
  return;
71
  }
admin/post-actions.php CHANGED
@@ -24,6 +24,11 @@ class Lingotek_Post_actions extends Lingotek_Actions {
24
  // add bulk actions.
25
  add_filter( 'bulk_actions-edit-post', array( &$this, 'add_bulk_actions' ) );
26
  add_filter( 'bulk_actions-edit-page', array( &$this, 'add_bulk_actions' ) );
 
 
 
 
 
27
 
28
  $polylang_enabled = PLL()->model->get_translated_post_types();
29
  $custom_post_types = get_post_types( array( '_builtin' => false ) );
@@ -273,7 +278,7 @@ class Lingotek_Post_actions extends Lingotek_Actions {
273
  $profiles = Lingotek::get_profiles();
274
  $content_profiles = get_option('lingotek_content_type');
275
  $language_profiles = self::retrieve_lang_Profiles($post_type, $profiles, $content_profiles);
276
- $default_name = empty($content_profiles) == false ? $profiles[$content_profiles[$post->post_type]['profile']]['name'] : ($post_type == 'page' ? __('Manual', 'lingotek-translation') : __('Automatic', 'lingotek-translation'));
277
  if ( ! isset( $default_name ) || 'disabled' === $default_name )
278
  {
279
  echo esc_html( __('You must enable translation for this content type in Lingotek\'s Content Type Configuration to enable Translation Profiles.', 'lingotek-translation') );
24
  // add bulk actions.
25
  add_filter( 'bulk_actions-edit-post', array( &$this, 'add_bulk_actions' ) );
26
  add_filter( 'bulk_actions-edit-page', array( &$this, 'add_bulk_actions' ) );
27
+
28
+ foreach(PLL()->model->get_translated_taxonomies() as $taxonomy) {
29
+ add_filter( "bulk_actions-edit-$taxonomy", array( &$this, 'add_bulk_actions' ) );
30
+ }
31
+ // add_filter( 'bulk_actions-edit-category', array( &$this, 'add_bulk_actions' ) );
32
 
33
  $polylang_enabled = PLL()->model->get_translated_post_types();
34
  $custom_post_types = get_post_types( array( '_builtin' => false ) );
278
  $profiles = Lingotek::get_profiles();
279
  $content_profiles = get_option('lingotek_content_type');
280
  $language_profiles = self::retrieve_lang_Profiles($post_type, $profiles, $content_profiles);
281
+ $default_name = empty($content_profiles) == false ? $profiles[$content_profiles[$post->post_type]['profile']]['name'] : __('Manual', 'lingotek-translation');
282
  if ( ! isset( $default_name ) || 'disabled' === $default_name )
283
  {
284
  echo esc_html( __('You must enable translation for this content type in Lingotek\'s Content Type Configuration to enable Translation Profiles.', 'lingotek-translation') );
admin/settings/view-account.php CHANGED
@@ -119,6 +119,46 @@ if ( ! $community_id ) {
119
  </select>
120
  </td>
121
  </tr>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
122
  </table>
123
 
124
  <?php submit_button( __( 'Save Changes', 'lingotek-translation' ), 'primary', 'submit', false ); ?>
119
  </select>
120
  </td>
121
  </tr>
122
+ <tr>
123
+ <th scope="row"><?php esc_html_e( 'Payment Method', 'lingotek-translation' ) ?></th>
124
+ <td>
125
+
126
+ <?php
127
+ add_thickbox();
128
+ wp_enqueue_script( 'lingotek_professional_workflow_account', LINGOTEK_URL . '/js/workflow/professional-workflow-account.js' );
129
+ $vars = array(
130
+ 'modal_id' => 'payment-portal-screen',
131
+ 'bridge_payment' => BRIDGE_URL . '/#/billing/payment'
132
+ );
133
+ wp_localize_script( 'lingotek_professional_workflow_account', 'account_vars', $vars );
134
+ wp_enqueue_style( 'lingotek_professional_workflow_style', LINGOTEK_URL . '/css/workflow/professional-workflow-style.css', array(), LINGOTEK_VERSION );
135
+ $ltk_client = new Lingotek_API();
136
+ $payment_info = $ltk_client->get_user_payment_information();
137
+ $cc = '';
138
+ $cc_type = '';
139
+ if ($payment_method_set = isset($payment_info['payment_info']['payment_profile']['cc'])) {
140
+ $cc = $payment_info['payment_info']['payment_profile']['cc'];
141
+ $cc = str_replace('X','', $cc);
142
+
143
+ $cc_type = $payment_info['payment_info']['payment_profile']['cc_type'];
144
+ }
145
+ ?>
146
+ <div id='modal-window-id-payment-portal-screen' style='display:none;' >
147
+ <div id='payment-portal-wrapper' class='payment-portal-element'>
148
+ <img class='payment-portal-element payment-portal-image' src="<?php echo esc_url_raw( LINGOTEK_URL ) ?>/img/translation-logo.png"/>
149
+ <img class='payment-portal-element payment-portal-loading' src="<?php echo esc_url_raw( LINGOTEK_URL ) ?>/img/loading.gif"/>
150
+ <span class='payment-portal-element You-are-now-being-re'>You are now being redirected to the Lingotek Secure Payment Portal...</span>
151
+ </div>
152
+ </div>
153
+ <div class='payment-method-setup professional-card-border' style="<?php echo ($payment_method_set) ? 'display:inline-block;' : 'display:none'; ?>">
154
+ <div class='payment-method-setup blue-radio-button-div'><img id='blue-radio-button' class='payment-method-setup' src="<?php echo esc_url_raw( LINGOTEK_URL ); ?>/img/blue-radio-button.svg"/></div>
155
+ <div class='payment-method-setup credit-card-dots-div'><img id='credit-card-dots' class='payment-method-setup' src="<?php echo esc_url_raw( LINGOTEK_URL ); ?>/img/credit-dots.svg" /></div>
156
+ <div class='payment-method-setup last-four-digits-div'><span id='last-four-digits' class='payment-method-setup'><?php echo $cc; ?></span></div>
157
+ <div class='payment-method-setup credit-card-image-div'><img id='credit-card-image' class='payment-method-setup' src="<?php echo Lingotek_Credit_Card_To_Path::get_cc_type_asset_url($cc_type) ?>"/></div>
158
+ </div>
159
+ <div style="height:37px; display:inline-block;padding-left: 10px;"><a id="professional-payment-info-link" href="<?php echo esc_url_raw( BRIDGE_URL ); ?>/#/billing/payment?redirect_url=<?php echo urlencode( home_url( add_query_arg( NULL, NULL ) ) ); ?>" style="display: table-cell;padding-top: 7%;"><?php echo ($payment_method_set) ? 'Edit Payment Method' : 'Setup Payment Method'; ?></a></div>
160
+ </td>
161
+ </tr>
162
  </table>
163
 
164
  <?php submit_button( __( 'Save Changes', 'lingotek-translation' ), 'primary', 'submit', false ); ?>
admin/strings-table.php CHANGED
@@ -61,12 +61,24 @@ class Lingotek_Strings_Table extends WP_List_Table {
61
  $language = $this->pllm->get_language( substr( $column_name, 9 ) );
62
  $document = $this->lgtm->get_group( 'string', $item['context'] ); // FIXME.
63
 
 
 
 
 
 
64
  $allowed_html = array(
65
- 'a' => array(
66
- 'class' => array(),
67
- 'title' => array(),
68
- 'href' => array(),
69
- ),
 
 
 
 
 
 
 
70
  );
71
  // post ready for upload.
72
  if ( $this->lgtm->can_upload( 'string', $item['context'] ) && $language->slug === $this->pllm->options['default_lang'] ) {
@@ -78,7 +90,7 @@ class Lingotek_Strings_Table extends WP_List_Table {
78
  elseif ( isset( $document->source ) && $document->source === $language->mo_id ) {
79
  echo wp_kses( 'importing' === $document->status ? Lingotek_Actions::importing_icon( $document ) : Lingotek_String_actions::uploaded_icon( $item['context'] ), $allowed_html );
80
  } // translations.
81
- elseif ( isset( $document->translations[ $language->locale ] ) || (isset( $document->source ) && 'current' === $document->status) ) {
82
  echo wp_kses( Lingotek_Actions::translation_icon( $document, $language ), $allowed_html );
83
  } // no translation.
84
  else { echo '<div class="lingotek-color dashicons dashicons-no"></div>';
@@ -103,7 +115,7 @@ class Lingotek_Strings_Table extends WP_List_Table {
103
  * @return string
104
  */
105
  function column_cb( $item ) {
106
- return sprintf( '<input type="checkbox" name="strings[]" value="%d" />', esc_attr( $item['row'] ) );
107
  }
108
 
109
  /**
61
  $language = $this->pllm->get_language( substr( $column_name, 9 ) );
62
  $document = $this->lgtm->get_group( 'string', $item['context'] ); // FIXME.
63
 
64
+
65
+ $workflow_id = Lingotek_Model::get_profile_option('workflow_id', 'string', $language);
66
+ $workflow = Lingotek_Workflow_Factory::get_workflow_instance( $workflow_id ); // TODO: put workflow_id here. It is currently not set up.
67
+ $workflow->echo_strings_modal($item['row'], $language->locale);
68
+
69
  $allowed_html = array(
70
+ 'a' => array(
71
+ 'class' => array(),
72
+ 'title' => array(),
73
+ 'href' => array(),
74
+ ),
75
+ 'img' => array(
76
+ 'src' => array()
77
+ ),
78
+ 'div' => array(
79
+ 'title' => array(),
80
+ 'class' => array(),
81
+ ),
82
  );
83
  // post ready for upload.
84
  if ( $this->lgtm->can_upload( 'string', $item['context'] ) && $language->slug === $this->pllm->options['default_lang'] ) {
90
  elseif ( isset( $document->source ) && $document->source === $language->mo_id ) {
91
  echo wp_kses( 'importing' === $document->status ? Lingotek_Actions::importing_icon( $document ) : Lingotek_String_actions::uploaded_icon( $item['context'] ), $allowed_html );
92
  } // translations.
93
+ elseif ( isset( $document->translations[ $language->locale ] ) || (isset( $document->source ) && 'current' === $document->status) && Lingotek::is_allowed_tms_locale($language->lingotek_locale)) {
94
  echo wp_kses( Lingotek_Actions::translation_icon( $document, $language ), $allowed_html );
95
  } // no translation.
96
  else { echo '<div class="lingotek-color dashicons dashicons-no"></div>';
115
  * @return string
116
  */
117
  function column_cb( $item ) {
118
+ return sprintf( '<input id="string-select-%s" type="checkbox" name="strings[]" value="%d" />', esc_attr( $item['row'] ), esc_attr( $item['row'] ) );
119
  }
120
 
121
  /**
admin/workflows/credit-card-to-path.php ADDED
@@ -0,0 +1,48 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ class Lingotek_Credit_Card_To_Path {
4
+
5
+ private $cc_type_map = array();
6
+ private $default_cc = 'Default';
7
+ private static $instance = null;
8
+
9
+
10
+ public static function get_url($cc_type) {
11
+ self::check_instantiated();
12
+ return self::$instance->get_cc_type_asset_url($cc_type);
13
+ }
14
+
15
+ public static function get_cc_map() {
16
+ self::check_instantiated();
17
+ return self::$instance->cc_type_map;
18
+ }
19
+
20
+ public static function get_cc_type_asset_url($cc_type) {
21
+ self::check_instantiated();
22
+ return isset( self::$instance->cc_type_map[ $cc_type ] ) ? self::$instance->cc_type_map[ $cc_type ] : self::$instance->cc_type_map[ self::$instance->default_cc ];
23
+ }
24
+
25
+ public static function get_default_cc_key() {
26
+ self::check_instantiated();
27
+ return self::$instance->default_cc;
28
+ }
29
+
30
+
31
+ private function __construct() {
32
+ $this->cc_type_map = array(
33
+ 'MasterCard' => LINGOTEK_URL . '/img/credit-cards/mastercard.svg',
34
+ 'AmericanExpress' => LINGOTEK_URL . '/img/credit-cards/amex.svg',
35
+ 'Discover' => LINGOTEK_URL . '/img/credit-cards/discover.svg',
36
+ 'JCB' => LINGOTEK_URL . '/img/credit-cards/jcb.svg',
37
+ 'DinersClub' => LINGOTEK_URL . '/img/credit-cards/diners.svg',
38
+ 'Visa' => LINGOTEK_URL . '/img/credit-cards/visa.svg',
39
+ $this->default_cc => LINGOTEK_URL . '/img/credit-cards/default.svg',
40
+ );
41
+ }
42
+
43
+ private static function check_instantiated() {
44
+ if (! self::$instance) {
45
+ self::$instance = new Lingotek_Credit_Card_To_Path();
46
+ }
47
+ }
48
+ }
admin/workflows/professional-translation-workflow.php CHANGED
@@ -2,104 +2,521 @@
2
 
3
  /**
4
  * Overrides uploads for Posts, Pages and Terms in order to display a modal and handle redirecting to bridge for payment.
 
5
  */
6
  class Lingotek_Professional_Translation_Workflow extends Lingotek_Workflow {
7
 
 
 
 
8
  /**
9
- * Adds the thickbox Wordpress component. Loades the professional-workflow js file that attaches listeners to uploads.
10
- * Sends the workflow id to the js file.
11
  *
12
  * @param string $id the workflow id.
13
  */
14
- public function override_events( $id ) {
15
- add_thickbox();
16
- wp_enqueue_script( 'lingotek_professional_workflow', LINGOTEK_URL . '/js/workflow/professional-workflow.js' );
17
- $vars = array(
18
- 'id' => $id,
19
- );
20
- wp_localize_script( 'lingotek_professional_workflow', 'workflow_vars', $vars );
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
21
  }
22
 
23
  /**
24
- * Writes a modal to the output buffer that contains information about this workflow.
25
  *
26
  * @param string $id the workflow id.
27
  */
28
- public function echo_info_modal( $id ) {
29
- if ( ! $this->info_modal_launched ) {
30
- $this->info_modal_launched = true;
31
- $args = array(
32
- 'header' => __( 'Professional Translation Workflow', 'lingotek-translation' ),
33
- 'body' => __( "The Professional Translation Workflow allows you to have any of your content
34
- translated professionally. Translations are priced by word count and can be requested from within
35
- the Wordpress Posts or Pages tab.
36
- <br><br>In order to use this workflow you must set up a payment method and purchase Word Credits.
37
- <br><br>Would you like to set up a payment method?", 'lingotek-translation' ),
38
- 'id' => $id,
39
- );
40
- $this->_echo_modal( $args );
41
  }
 
42
  }
43
 
 
44
  /**
45
  * Writes a modal to the output buffer that tells the user how much it is going to cost.
46
  *
47
  * @param string $id the workflow id.
48
  */
49
- public function echo_posts_modal( $id ) {
50
- if ( ! $this->post_modal_launched ) {
51
- $this->post_modal_launched = true;
52
- $args = array(
53
- 'header' => __( 'Confirm Document Upload', 'lingotek-translation' ),
54
- 'body' => __( "You have the Professional Translation workflow selected. This means that all
55
- translations of this document will cost Word Credits.
56
- <br><br>Any translations of the uploaded document will be <b>final</b>. A new transaction(s) will be made if this document is
57
- edited and re-translations are requested.
58
- <br><br>Would you like to continue?", 'lingotek-translation' ),
59
- 'id' => $id,
60
- );
61
- $this->_echo_modal( $args );
62
- $this->echo_request_modal( $id );
63
  }
 
64
  }
65
 
66
-
67
  /**
68
  * Writes a modal to the output buffer that tells the user how much it is going to cost.
69
  *
70
  * @param string $id the workflow id.
71
  */
72
- public function echo_terms_modal( $id ) {
73
- if ( ! $this->terms_modal_launched ) {
74
- $this->terms_modal_launched = true;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
75
  $args = array(
76
- 'header' => __( 'Lingotek Terms', 'lingotek-translation' ),
77
- 'body' => __( 'This is an example of a terms modal.', 'lingotek-translation' ),
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
78
  'id' => $id,
79
  );
80
  $this->_echo_modal( $args );
81
- $this->echo_request_modal( $id );
82
  }
 
83
 
 
 
 
 
 
 
 
84
  }
85
 
86
  /**
87
- * Writes a modal to the output buffer that is launched when the user clicks on the 'request translation'
88
- * option.
89
  *
90
- * @param string $id the workflow id.
91
  */
92
- public function echo_request_modal( $id ) {
93
- $args = array(
94
- 'header' => __( 'Confirm Request Translation', 'lingotek-translation' ),
95
- 'body' => __( "You have the Professional Translation workflow selected. This document will be translated by a professional
96
- in the selected language.
97
-
98
- <br><br>The approximated cost to translate this document is 13 Word Credits.
99
- <br><br>The translation request is <b>final</b> meaning that if the source document is changed then it will cost Word Credits to request re-translation.
100
- <br><br> Would you like to request this translation?", 'lingotek-translation' ),
101
- 'id' => $id . '-request',
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
102
  );
103
- $this->_echo_modal( $args );
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
104
  }
105
  }
2
 
3
  /**
4
  * Overrides uploads for Posts, Pages and Terms in order to display a modal and handle redirecting to bridge for payment.
5
+ * The base class contains better documentation on what each individual function means.
6
  */
7
  class Lingotek_Professional_Translation_Workflow extends Lingotek_Workflow {
8
 
9
+
10
+ private static $item_id_list = array();
11
+
12
  /**
13
+ * Writes a modal to the output buffer that contains information about this workflow.
 
14
  *
15
  * @param string $id the workflow id.
16
  */
17
+ public function echo_info_modal( $item_id = null, $item_type = null ) {
18
+ if (Lingotek_Professional_Translation_Workflow::is_allowed_user()) {
19
+ if ( ! self::$info_modal_launched ) {
20
+ self::$info_modal_launched = true;
21
+
22
+ wp_enqueue_script( 'lingotek_professional_workflow_defaults', LINGOTEK_URL . '/js/workflow/professional-workflow-defaults.js' );
23
+
24
+ $client = new Lingotek_API();
25
+
26
+ $payment_info = $client->get_user_payment_information();
27
+
28
+ $vars = array(
29
+ 'workflow_id' => $this->workflow_id,
30
+ 'bridge_payment' => BRIDGE_URL . '/#/billing/payment',
31
+ 'translation_icon' => LINGOTEK_URL . '/img/translation-logo.png',
32
+ 'loading_gif' => LINGOTEK_URL . '/img/loading.gif',
33
+ 'icon_url' => LINGOTEK_URL . '/img/lingotek-logo-white.png',
34
+ 'payment_info' => $payment_info
35
+ );
36
+ wp_localize_script( 'lingotek_professional_workflow_defaults', 'professional_vars', $vars );
37
+
38
+ wp_enqueue_style( 'lingotek_professional_workflow_style', LINGOTEK_URL . '/css/workflow/professional-workflow-style.css', array(), LINGOTEK_VERSION );
39
+ $args = array(
40
+ 'parent_elements' => $this->get_payment_portal_html(),
41
+ 'body' => __( "
42
+
43
+ <div class='Youve-Selected-Prof'>You've Selected Professional Translation</div><br>
44
+
45
+ <div class='By-Selecting-this-op'>
46
+ By selecting this option as your workflow you will be able to request professional translations through Lingotek’s Languages Services.
47
+ Please click the \"ADD PAYMENT METHOD\" button to use this service.
48
+ </div><br><br><br>
49
+
50
+ <div class='Note-By-using-the-'>
51
+ Note: By using the 'Lingotek Professional Translation' workflow you will be asked to confirm payment before the professional translation request is processed.
52
+ </div>
53
+
54
+ <button type='button' id='no-" . esc_attr( $this->workflow_id ) . "' class='background-test float-bottom-right-next-to-default'>
55
+ <span class='ADD-PAYMENT-LATER'>LATER</span>
56
+ </button>
57
+ <button type='button' id='yes-" . esc_attr( $this->workflow_id ) . "' class='prefessional-action-button-default float-bottom-right'>
58
+ <span class='ADD-PAYMENT'>ADD PAYMENT METHOD</span>
59
+ </button>
60
+ </div>
61
+
62
+ ", 'lingotek-translation' ),
63
+ 'id' => $this->workflow_id,
64
+ );
65
+ $this->_echo_modal( $args );
66
+ }
67
+ }
68
  }
69
 
70
  /**
71
+ * Writes a modal to the output buffer that tells the user how much it is going to cost.
72
  *
73
  * @param string $id the workflow id.
74
  */
75
+ public function echo_posts_modal( $item_id = null, $wp_locale = null, $item_type = null ) {
76
+ $this->add_item_id($item_id, $wp_locale);
77
+ if (Lingotek_Professional_Translation_Workflow::is_allowed_user()) {
78
+ if ( ! self::$post_modal_launched ) {
79
+ self::$post_modal_launched = true;
80
+ $this->echo_upload_warning_modal();
81
+ $this->echo_request_modal( 'post' );
82
+ }
 
 
 
 
 
83
  }
84
+ $this->flush_list();
85
  }
86
 
87
+
88
  /**
89
  * Writes a modal to the output buffer that tells the user how much it is going to cost.
90
  *
91
  * @param string $id the workflow id.
92
  */
93
+ public function echo_terms_modal( $item_id = null, $wp_locale = null, $item_type = null ) {
94
+ $this->add_item_id($item_id, $wp_locale);
95
+ if (Lingotek_Professional_Translation_Workflow::is_allowed_user())
96
+ {
97
+ if ( ! self::$terms_modal_launched ) {
98
+ self::$terms_modal_launched = true;
99
+ $this->echo_upload_warning_modal();
100
+ $this->echo_request_modal( 'term' );
101
+ }
 
 
 
 
 
102
  }
103
+ $this->flush_list();
104
  }
105
 
 
106
  /**
107
  * Writes a modal to the output buffer that tells the user how much it is going to cost.
108
  *
109
  * @param string $id the workflow id.
110
  */
111
+ public function echo_strings_modal( $item_id = null, $wp_locale = null, $item_type = null ) {
112
+ $this->add_item_id($item_id, $wp_locale);
113
+ if (Lingotek_Professional_Translation_Workflow::is_allowed_user())
114
+ {
115
+ if ( ! self::$strings_modal_launched ) {
116
+ self::$strings_modal_launched = true;
117
+ $this->echo_upload_warning_modal();
118
+ $this->echo_request_modal( 'string' );
119
+ }
120
+ }
121
+ $this->flush_list();
122
+ }
123
+
124
+ /**
125
+ * Writes a modal to the output buffer that tells the user if certain translations will
126
+ * be overwritten by a given action.
127
+ *
128
+ * @param string $id the workflow id.
129
+ */
130
+ private function echo_upload_warning_modal() {
131
+ $id = $this->workflow_id . '-warning';
132
+ $args = array(
133
+ 'header' => __( 'Confirm Document Upload', 'lingotek-translation' ),
134
+ 'body' => __( "
135
+ <div id='warning-wrapper'>
136
+ <div class='professional-upload-warning-header-container'>
137
+ <span class='professional-upload-warning-header'>By uploading these changes, your professional translations may be lost.</span>
138
+ </div>
139
+
140
+ <div class='professional-upload-warning-body-container'>
141
+ <span class='professional-upload-warning-body'>
142
+ By editing this document and then re-uploading it to Lingotek any professional translations that you have not downloaded yet will be lost. Additionally, any professional translations that are in-progress for this document will be lost.
143
+ </span>
144
+ </div>
145
+
146
+ <div class='professional-warning-checkbox-container'><input id='professional-warning-checkbox' type='checkbox' name='confirm-request' value='professional-warning-upload></div>
147
+ <div class='professional-warning-checkbox-text-container'><span class='professional-warning-checkbox-text'> I understand that translations that have not been downloaded or that are in progress will be lost and money paid for that translation will be forfeited by re-uploading them to Lingotek.</span></div>
148
+
149
+ <button type='button' id='cancel-warning-" . esc_attr( $id ) . "' class='professional-cancel-button float-bottom-right-next-to'>
150
+ <span class='ADD-PAYMENT-LATER'>CANCEL</span>
151
+ </button>
152
+ <div class='float-bottom-right' style='bottom:5%;'><img id='professional-warning-loading-spinner' style='display:none;' src='". esc_url_raw( LINGOTEK_URL ) ."/img/loading_mini.gif' /></div>
153
+ <button type='button' id='ok-warning-" . esc_attr( $id ) . "' class='professional-okay-warning-button-disabled float-bottom-right' disabled='true'>
154
+ <span id='professional-warning-okay-text' class='ADD-PAYMENT-DISABLED'>PROCEED</span>
155
+ </button>
156
+
157
+ </div>", 'lingotek-translation' ),
158
+ 'id' => $id,
159
+ );
160
+ $this->_echo_modal( $args );
161
+ }
162
+
163
+ /**
164
+ * Writes a modal to the output buffer that is launched when the user clicks on the 'request translation'
165
+ * option.
166
+ *
167
+ * @param string $id the workflow id.
168
+ */
169
+ public function echo_request_modal( $type ) {
170
+ if (Lingotek_Professional_Translation_Workflow::is_allowed_user())
171
+ {
172
+ $this->load_request_scripts_and_styles( $type );
173
+ $id = $this->workflow_id . '-request';
174
  $args = array(
175
+ 'header' => __( 'Confirm Request Translation', 'lingotek-translation' ),
176
+ 'parent_elements' => "
177
+ <img class='loading-element loading-translations-image' src='" . esc_url_raw( LINGOTEK_URL ) . "/img/translation-logo.png'/>
178
+ <div class='loading-element loading-progress-bar-outer'>
179
+ <div class='loading-element loading-progress-bar-inner'></div>
180
+ </div>
181
+ <span class='loading-element loading-progress-percent'>65%</span>
182
+ <div class='loading-element Analyzing-translations'>Analyzing translations and gathering quotes...</div>
183
+ ",
184
+ 'body' => __( "
185
+ <div id='wrapper'>
186
+ <div id='content'><br>
187
+ <div id='professional-table-content'>
188
+ <span class='Congratulations-You payment-method-setup'>You have elected to use our Professional Translation Services.<br><br></span>
189
+ <div class='You-can-now-connect payment-method-setup'>
190
+ You can now connect with audiences around the globe using Lingotek's network of 5000+ professional, in-country, translators. Professional Translation ensures that your audiences will feel the sentiment of your content.
191
+ </div>
192
+ <div class='minimum-per-language-warning minimum-warning payment-method-setup'>
193
+ <img class='payment-method-setup' src='". esc_url_raw( LINGOTEK_URL ) ."/img/minimum-warning.svg' />
194
+ <span class='payment-method-setup' >*$59.99 minimum per language.</span>
195
+ <span class='payment-method-setup' ltk-data-tooltip='This minimum ensures that we can retain the best professional linguists for your translation job.'><img src='". esc_url_raw( LINGOTEK_URL ) ."/img/minimum-help.svg' /></span>
196
+ </div>
197
+ <br class='payment-method-setup'>
198
+ <span class='Translation-Request payment-method-setup'>Translation Request Summary<br><br></span>
199
+
200
+
201
+ <span class='Congratulations-You payment-not-setup'>Welcome to Lingotek's Translation Quote Calculator<br><br></span>
202
+ <div class='You-can-now-connect payment-not-setup'>
203
+ Using the quote calculator below you can get an idea of how much your translations will cost. You will need to add a payment method to the Lingotek Secure Payment Portal In order to purchase these translations.
204
+ </div>
205
+ <br class='payment-not-setup'>
206
+ <div class='minimum-per-language-warning minimum-warning payment-not-setup'>
207
+ <img class='payment-not-setup' src='". esc_url_raw( LINGOTEK_URL ) ."/img/minimum-warning.svg' />
208
+ <span class='payment-not-setup'>*$59.99 minimum per language.</span>
209
+ <span class='payment-not-setup' ltk-data-tooltip='This minimum ensures that we can retain the best professional linguists for your translation job.'><img src='". esc_url_raw( LINGOTEK_URL ) ."/img/minimum-help.svg' /></span>
210
+ </div>
211
+ <br class='payment-not-setup'>
212
+ <span class='Translation-Request payment-not-setup'>Translation Quotes<br><br></span>
213
+ <div id='table-wrapper'>
214
+ <table class='request-table'>
215
+ <tr class='bordered-bottom'><th style='display: table-cell;' class='table-header'>Title</th><th style='display: table-cell;' class='table-header' id='words-column'>Words</th><th style='text-align:center;'><a href='#' id='next-language-set'> <img id='next-language-image' src='" . esc_url_raw( LINGOTEK_URL ) . "/img/right-arrow.svg' /> </a> </th><th class='table-header table-total invisible'>Total</th></tr>
216
+ </table>
217
+ </div>
218
+ </div>
219
+ <div id='professional-terms-and-conditions'>
220
+ <span class='terms-and-conditions-header'>Lingotek Terms and Conditions</span><br><br>
221
+ <div class='terms-and-conditions-content'>
222
+
223
+
224
+
225
+
226
+
227
+
228
+
229
+
230
+
231
+
232
+ <img id='terms-of-service-loading-ltk' src='". esc_url_raw( LINGOTEK_URL ) ."/img/loading.gif'/>
233
+
234
+
235
+
236
+
237
+
238
+
239
+
240
+
241
+
242
+ </div>
243
+ <button type='button' id='close-terms-and-conditions'>
244
+ <span class='CLOSE-TERMS-CONDITIONS'>CLOSE</span>
245
+ </button>
246
+ </div>
247
+ </div>
248
+ <div id='sidebar'>
249
+ <span class='Payment-Method payment-method-setup'>Payment Method</span><br class='payment-method-setup'><br class='payment-method-setup'>
250
+ <span class='payment-method-setup credit-card-header'>Credit Card</span><br class='payment-method-setup'><br class='payment-method-setup'>
251
+ <div class='payment-method-setup professional-card-border'>
252
+ <div class='payment-method-setup blue-radio-button-div'><img id='blue-radio-button' class='payment-method-setup' src='" . esc_url_raw( LINGOTEK_URL ) . "/img/blue-radio-button.svg'/></div>
253
+ <div class='payment-method-setup credit-card-dots-div'><img id='credit-card-dots' class='payment-method-setup' src='" . esc_url_raw( LINGOTEK_URL ) . "/img/credit-dots.svg'/></div>
254
+ <div class='payment-method-setup last-four-digits-div'><span id='last-four-digits' class='payment-method-setup'>XXXX</span></div>
255
+ <div class='payment-method-setup credit-card-image-div'><img id='credit-card-image' class='payment-method-setup' src='" . Lingotek_Credit_Card_To_Path::get_cc_type_asset_url( Lingotek_Credit_Card_To_Path::get_default_cc_key() ) . "'/></div>
256
+ </div>
257
+ <br class='payment-method-setup'>
258
+ <br class='payment-method-setup'>
259
+
260
+
261
+ <span class='Payment-Method payment-not-setup'>Benefits of Professional Translation</span><br class='payment-not-setup'>
262
+ <ul class='translation-summary-list payment-not-setup'>
263
+ <li><span class='translation-summary-list-text'>Translations will be translated by professional in-country linguists.</span></li>
264
+ <li><span class='translation-summary-list-text'>Receive your translations in just a few days.</span></li>
265
+ <li><span class='translation-summary-list-text'>100% customer satisfaction guarantee.</span></li>
266
+ </ul>
267
+ <br class='payment-not-setup'>
268
+ <span class='Translation-Request-Right payment-method-setup'>Translation Request Summary</span>
269
+ <span class='Translation-Request-Right payment-not-setup'>Translation Quote Summary</span>
270
+ <ul class='translation-summary-list translation-summary-list-ltk'>
271
+
272
+ </ul>
273
+ <div class='minimum-disclaimer'>*Minimum charge $59.99 per language</div>
274
+ <br>
275
+ <div style='float:right;'>
276
+ <span class='request-total'>TOTAL: </span><span class='lingotek-total-amount'></span>
277
+ </div>
278
+
279
+ <div class='ltk-request-payment-disclaimer payment-method-setup'>
280
+ Note: By clicking the 'Buy Now' button your translations will be requested and you will be charged for the amount shown above.
281
+ </div>
282
+
283
+
284
+ <br class='payment-not-setup'><br class='payment-not-setup'><br class='payment-not-setup'>
285
+ <div class='disclaimer-request payment-not-setup'>
286
+ Note: By clicking the 'Add Payment Method' button you will be redirected to the Lingotek Secure Payment Portal.
287
+ Please note that none of the selections you have made in the table will be saved.
288
+ </div>
289
+ <br class='payment-method-setup'><br class='payment-method-setup'>
290
+
291
+ <div class='delivery-estimation'>Estimated delivery: <span class='business-days'>3 - 5 business days.</span><span ltk-data-tooltip='This is an estimate, not a guaranteed delivery time.'><img src='". esc_url_raw( LINGOTEK_URL ) ."/img/minimum-help.svg' /></span></div>
292
+ <div class='request-checkbox payment-method-setup'><input id='accept-terms-and-conditions-input' type='checkbox' name='confirm-request' value='request-translation><span class='terms-conditions'> I agree to the <a id='terms-and-conditions-href' href='#'>Lingotek Terms and Conditions</a></span></div>
293
+ <br class='payment-method-setup'>
294
+
295
+ <button type='button' id='yes-" . esc_attr( $id ) . "-add-payment' class='professional-action-button float-center payment-not-setup' style='float:left'>
296
+ <span id='professional-add-payment' class='ADD-PAYMENT payment-not-setup'>ADD PAYMENT METHOD</span>
297
+ </button>
298
+ <button type='button' id='yes-" . esc_attr( $id ) . "-buy-now' class='professional-action-button-disabled float-center payment-method-setup' style='float:left; bottom:-2%;' disabled='true'>
299
+ <span id='professional-buy-now' class='ADD-PAYMENT-DISABLED payment-method-setup'>BUY NOW</span>
300
+ </button>
301
+ </div>
302
+ <div id='cleared'></div>
303
+ </div>
304
+
305
+
306
+ <div id='requesting-translation-screen' class='requesting-element'>
307
+ <img class='requesting-element payment-portal-image' src='". esc_url_raw( LINGOTEK_URL ) ."/img/translation-logo.png'/>
308
+ <img class='requesting-element payment-portal-loading' src='". esc_url_raw( LINGOTEK_URL ) ."/img/loading.gif'/>
309
+ <div class='requesting-element Analyzing-translations'>Requesting Translations</div>
310
+ </div>
311
+
312
+ <div id='requesting-translation-success-screen' class='professional-translation-request-success-element'>
313
+ <img class='professional-translation-request-success-element payment-portal-image' src='". esc_url_raw( LINGOTEK_URL ) ."/img/translation-logo.png'/>
314
+ <img class='professional-translation-request-success-element green-check-success' src='" . esc_url_raw( LINGOTEK_URL ) . "/img/checkmark-green.svg'/>
315
+ <div class='professional-translation-request-success-element professional-translation-view-invoice' style='height: 28px;'>Your translations have been successfully requested.</div>
316
+ <div class='professional-translation-request-success-element professional-translation-view-invoice'>You will be receiving a confirmation email shortly.</div>
317
+ <div class='professional-translation-request-success-element professional-translation-view-invoice'>Your credit card will be charged <span id='professional-translation-cost-success' class='professional-translation-request-success-element'></span></div>
318
+ <button type='button' id='professional-post-transaction-button' class='professional-translation-request-success-element professional-view-invoice-btn float-center'>
319
+ <span id='professional-post-transaction' class='ADD-PAYMENT professional-translation-request-success-element'>OK</span>
320
+ </button>
321
+ </div>
322
+
323
+
324
+
325
+ <div id='requesting-translation-error-screen' class='professional-translation-request-error-element'>
326
+ <img class='professional-translation-request-error-element payment-portal-image' src='". esc_url_raw( LINGOTEK_URL ) ."/img/translation-logo.png'/>
327
+ <img class='professional-translation-request-error-element green-check-success' src='" . esc_url_raw( LINGOTEK_URL ) . "/img/error.svg'/>
328
+ <div id='error-requesting-translation-ltk' class='professional-translation-request-error-element professional-translation-view-invoice'>There was an error requesting your translation.</div>
329
+ <div id='error-requesting-translation-ltk-2' class='professional-translation-request-error-element professional-translation-view-invoice'>Please refresh the page and try again.</div>
330
+ <button type='button' id='professional-post-transaction-button' class='professional-translation-request-error-element professional-view-invoice-btn float-center'>
331
+ <span id='professional-post-transaction-failure' class='ADD-PAYMENT professional-translation-request-error-element'>Ok</span>
332
+ </button>
333
+ </div>
334
+
335
+ </div>
336
+ ".$this->get_payment_portal_html()."
337
+
338
+ ", 'lingotek-translation' ),
339
  'id' => $id,
340
  );
341
  $this->_echo_modal( $args );
 
342
  }
343
+ }
344
 
345
+ /**
346
+ * This method will be used to roll out the Professional Translation workflow to a select number of users.
347
+ * The method will be called before anything is sent to the client.
348
+ */
349
+ public static function is_allowed_user()
350
+ {
351
+ return true;
352
  }
353
 
354
  /**
355
+ * We store the document id's of the documents we have already disassociated
356
+ * so that we don't make redundant calls to disassociate a document.
357
  *
358
+ * @var array
359
  */
360
+ private static $pre_uploaded = array();
361
+
362
+ /**
363
+ * We disassociate the document before uploading to avoid automatic requesting of translations.
364
+ *
365
+ * @param string $item_id
366
+ * @param string $type
367
+ * @return void
368
+ */
369
+ public function pre_upload_to_lingotek($item_id, $type) {
370
+ $lgtm = new Lingotek_Model();
371
+ if ($document = $lgtm->get_group($type, $item_id)) {
372
+ if (isset(self::$pre_uploaded[$document->document_id])) { return; }
373
+ self::$pre_uploaded[$document->document_id] = true;
374
+ $document->disassociate();
375
+ }
376
+ }
377
+
378
+
379
+ /**
380
+ * When a quick edit is performed it is done over AJAX. The front end is dependent upon many event
381
+ * listeners to keep track of what the user is clicking on and what should be shown in the modal. Because quick edit is
382
+ * done over AJAX, we send a page refresh so that our listeners can re-attach. This is not the preferred solution - feel free
383
+ * to change this (whether on the backend or front end) as a better solution appears.
384
+ *
385
+ * @return void
386
+ */
387
+ public function save_post_hook() {
388
+ if (! self::$save_post_hook_executed) {
389
+ self::$save_post_hook_executed = true;
390
+ $post_vars = filter_input_array(INPUT_POST);
391
+
392
+ if ('inline-save' === $post_vars['action']) {
393
+ echo '<script>location.reload();</script>';
394
+ }
395
+ }
396
+ }
397
+
398
+ /**
399
+ * When a quick edit is performed it is done over AJAX. The front end is dependent upon many event
400
+ * listeners to keep track of what the user is clicking on and what should be shown in the modal. Because quick edit is
401
+ * done over AJAX, we send a page refresh so that our listeners can re-attach. This is not the preferred solution - feel free
402
+ * to change this (whether on the backend or front end) as a better solution appears.
403
+ *
404
+ * @return void
405
+ */
406
+ public function save_term_hook() {
407
+ if (! self::$save_terms_hook_executed) {
408
+ self::$save_terms_hook_executed = true;
409
+ $post_vars = filter_input_array(INPUT_POST);
410
+
411
+ if ('inline-save-tax' === $post_vars['action']) {
412
+ echo '<script>location.reload();</script>';
413
+ }
414
+ }
415
+ }
416
+
417
+ /**
418
+ * We request translations over Bridge.
419
+ *
420
+ * @return boolean
421
+ */
422
+ public function has_custom_request_procedure() { return true; }
423
+
424
+ /**
425
+ * We don't want documents being uploaded automatically because of the chance
426
+ * that a user may lose translations that they have paid for if they haven't finished or downloaded.
427
+ *
428
+ * @return void
429
+ */
430
+ public function auto_upload_allowed() { return false; }
431
+
432
+
433
+ public function get_custom_in_progress_icon() {
434
+ return '<div title="Professional translation in progress" class="lingotek-professional-icon"><img src="'. LINGOTEK_URL . '/img/human-translation.svg" /></div>';
435
+ }
436
+
437
+ /**
438
+ * This loads the js and css files that handle the showing of the modals.
439
+ *
440
+ * @param string $type
441
+ * @return void
442
+ */
443
+ private function load_request_scripts_and_styles($type)
444
+ {
445
+ add_thickbox();
446
+ wp_enqueue_script( 'lingotek_professional_workflow', LINGOTEK_URL . '/js/workflow/professional-workflow.js' );
447
+ wp_enqueue_style( 'lingotek_professional_workflow_style', LINGOTEK_URL . '/css/workflow/professional-workflow-style.css', array(), LINGOTEK_VERSION );
448
+
449
+ $client = new Lingotek_API();
450
+
451
+ $language_mappings = $client->get_language_mappings();
452
+ $locales_list = PLL()->model->get_languages_list();
453
+
454
+ $enabled_langs = array();
455
+ foreach ($locales_list as $locale)
456
+ {
457
+ $lingotek_gmc_locale = str_replace('-', '_', $locale->lingotek_locale);
458
+ $enabled_langs[$locale->locale] = array(
459
+ 'lingotek_locale' => $locale->lingotek_locale,
460
+ 'language' => $language_mappings[$lingotek_gmc_locale]['language_name'],
461
+ 'country_name' => $language_mappings[$lingotek_gmc_locale]['country_name']
462
+ );
463
+ }
464
+
465
+ $vars = array(
466
+ 'workflow_id' => $this->workflow_id,
467
+ 'icon_url' => LINGOTEK_URL . '/img/lingotek-logo-white.png',
468
+ 'question_mark_icon_url' => LINGOTEK_URL . '/img/questionmark.svg',
469
+ 'bridge_payment_redirect' => BRIDGE_URL . '/#/billing/payment',
470
+ 'enabled_langs' => $enabled_langs,
471
+ 'curr_item_type' => $type,
472
+ 'cc_type_map' => Lingotek_Credit_Card_To_Path::get_cc_map(),
473
+ 'default_cc_type' => Lingotek_Credit_Card_To_Path::get_default_cc_key(),
474
+ 'nonce' => wp_create_nonce( 'lingotek_professional' )
475
  );
476
+ wp_localize_script( 'lingotek_professional_workflow', 'workflow_vars', $vars );
477
+ }
478
+
479
+
480
+ /**
481
+ * As the table is being built (for posts, pages, terms, etc.) we only want to attach listeners to locales that have the professional
482
+ * workflow enabled. This list is build as the table is being rendered.
483
+ *
484
+ * @param string $item_id
485
+ * @param string $wp_locale
486
+ * @return void
487
+ */
488
+
489
+ private function add_item_id( $item_id, $wp_locale ) {
490
+ self::$item_id_list[$item_id][] = $wp_locale;
491
+ }
492
+
493
+ /**
494
+ * Because a new workflow object is created every time a new locale is rendered on the table we can't preserve the list in a single object.
495
+ * Instead, we store that list statically and update the list that will eventually be sent to the front end everytime a workflow object is destroyed.
496
+ *
497
+ * @return void
498
+ */
499
+ private function flush_list()
500
+ {
501
+ $vars = array(
502
+ 'ids' => self::$item_id_list,
503
+ );
504
+ wp_localize_script( 'lingotek_professional_workflow', 'item_ids', $vars );
505
+ }
506
+
507
+ /**
508
+ * Returns the HTML that displays the payment portal loading screen.
509
+ *
510
+ * @return void
511
+ */
512
+ private function get_payment_portal_html()
513
+ {
514
+ return "
515
+ <div id='payment-portal-wrapper' class='payment-portal-element'>
516
+ <img class='payment-portal-element payment-portal-image' src='". esc_url_raw( LINGOTEK_URL ) ."/img/translation-logo.png'/>
517
+ <img class='payment-portal-element payment-portal-loading' src='". esc_url_raw( LINGOTEK_URL ) ."/img/loading.gif'/>
518
+ <span class='payment-portal-element You-are-now-being-re'>You are now being redirected to the Lingotek Secure Payment Portal...</span>
519
+ </div>
520
+ ";
521
  }
522
  }
admin/workflows/workflow-factory.php CHANGED
@@ -15,6 +15,10 @@ class Lingotek_Workflow_Factory {
15
  public function __construct() {
16
  self::class_load( self::BASE_WORKFLOW );
17
  wp_enqueue_script( 'lingotek_workflow_namespace', LINGOTEK_URL . '/js/workflow/workflow.js' );
 
 
 
 
18
  }
19
  /**
20
  * An associative array that maps a workflowId to a Workflow object.
@@ -22,7 +26,8 @@ class Lingotek_Workflow_Factory {
22
  * @var array
23
  */
24
  private static $map = array(
25
- 'professional-translation' => 'Lingotek_Professional_Translation_Workflow',
 
26
  );
27
 
28
  /**
@@ -39,7 +44,7 @@ class Lingotek_Workflow_Factory {
39
  else
40
  {
41
  self::class_load( self::$map[ $workflow_id ] );
42
- return new self::$map[ $workflow_id ]();
43
  }
44
  }
45
 
@@ -49,8 +54,8 @@ class Lingotek_Workflow_Factory {
49
  public static function echo_info_modals() {
50
  add_thickbox();
51
  foreach ( self::$map as $id => $class ) {
52
- $workflow = new $class();
53
- $workflow->echo_info_modal( $id );
54
  }
55
  }
56
 
15
  public function __construct() {
16
  self::class_load( self::BASE_WORKFLOW );
17
  wp_enqueue_script( 'lingotek_workflow_namespace', LINGOTEK_URL . '/js/workflow/workflow.js' );
18
+ $vars = array(
19
+ 'icon_url' => LINGOTEK_URL . '/img/lingotek-logo-white.png',
20
+ );
21
+ wp_localize_script( 'lingotek_workflow_namespace', 'modal_vars', $vars );
22
  }
23
  /**
24
  * An associative array that maps a workflowId to a Workflow object.
26
  * @var array
27
  */
28
  private static $map = array(
29
+ 'ab6c522a-7645-4317-9284-3fbddf516151' => 'Lingotek_Professional_Translation_Workflow', // prod.
30
+ '2e3694ae-9912-4a57-be47-cd1f8a08c469' => 'Lingotek_Professional_Translation_Workflow', // cms.
31
  );
32
 
33
  /**
44
  else
45
  {
46
  self::class_load( self::$map[ $workflow_id ] );
47
+ return new self::$map[ $workflow_id ]( $workflow_id );
48
  }
49
  }
50
 
54
  public static function echo_info_modals() {
55
  add_thickbox();
56
  foreach ( self::$map as $id => $class ) {
57
+ $workflow = new $class( $id );
58
+ $workflow->echo_info_modal();
59
  }
60
  }
61
 
admin/workflows/workflow.php CHANGED
@@ -5,13 +5,94 @@
5
  */
6
  class Lingotek_Workflow {
7
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
8
  /**
9
  * If a modal has already been written to the output buffer then we don't
10
  * want to write it again.
11
  *
12
  * @var boolean
13
  */
14
- protected $info_modal_launched = false;
15
 
16
  /**
17
  * If a modal has already been written to the output buffer then we don't
@@ -19,7 +100,16 @@ class Lingotek_Workflow {
19
  *
20
  * @var boolean
21
  */
22
- protected $post_modal_launched = false;
 
 
 
 
 
 
 
 
 
23
 
24
  /**
25
  * If a modal has already been written to the output buffer then we don't
@@ -27,15 +117,48 @@ class Lingotek_Workflow {
27
  *
28
  * @var boolean
29
  */
30
- protected $terms_modal_launched = false;
31
 
32
  /**
33
- * This method is called when the Posts or Pages pages are loaded. The overriding class may choose to
34
- * load a custom js file to handle events or do any sort of custom 'prep work'.
35
  *
36
- * @param string $id the workflow id.
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
37
  */
38
- public function override_events( $id ) {}
 
 
 
 
 
 
 
 
 
 
39
 
40
  /**
41
  * Writes a modal to the output buffer. This is called when the Translation > Settings > Defaults pages is loaded.
@@ -45,30 +168,93 @@ class Lingotek_Workflow {
45
  *
46
  * @param string $id the workflow id.
47
  */
48
- public function echo_info_modal( $id ) {}
49
 
50
  /**
51
  * This method is called when the Posts or Pages columns are being rendered.
52
  *
53
- * @param string $id the workflow id.
 
 
54
  */
55
- public function echo_posts_modal( $id ) {}
56
 
57
  /**
58
  * This method is called when the Terms table is being rendered.
59
  *
60
- * @param string $id the workflow id.
 
 
61
  */
62
- public function echo_terms_modal( $id ) {}
 
63
 
64
  /**
65
- * This method writes the modal that should be displayed when
66
- * the request icon is clicked.
67
  *
68
- * @param string $id the workflow id.
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
69
  */
70
- public function echo_request_modal( $id ) {}
 
71
 
 
72
  /**
73
  * This method acts as a template for building the modals. The arguments passed
74
  * are inserted into the html string and then echo'd. If any extra html elements
@@ -84,44 +270,45 @@ class Lingotek_Workflow {
84
  */
85
  add_filter( 'safe_style_css', array(&$this, 'add_modal_styles'));
86
 
87
- $allowed_html = array(
88
- 'div' => array(
89
- 'id' => array(),
90
- 'style' => array(),
91
- ),
92
- 'h2' => array(
93
- 'style' => array(),
94
- ),
95
- 'br' => array(),
96
- 'b' => array(),
97
- 'p' => array(
98
- 'style' => array(),
99
- ),
100
- 'a' => array(
101
- 'id' => array(),
102
- 'href' => array(),
103
- 'style' => array(),
104
- 'class' => array()
105
- ),
106
- );
107
  $id = isset( $args['id'] ) ? '-' . $args['id'] : '';
108
- echo wp_kses( "<div id='modal-window-id" . esc_attr( $id ) . "' style='display:none; height:100%;' >
109
- <h2 style='text-align:center; font-size:large;'>" . esc_html( $args['header'] ) . "</h2>
110
- <p style='text-align:center; font-size:110%;'>" . wp_kses( $args['body'], $allowed_html ) . "</p>
111
- <br>
112
- <a id='yes" . esc_attr( $id ) . "' class='lingotek-color dashicons' href='#' style='position:absolute; float:left; bottom:30px;'>Continue</a>
113
- <div style='float:right; padding-right:55px;'>
114
- <a id='no" . esc_attr( $id ) . "' class='lingotek-color dashicons' href='#' style='position:absolute; float:right; bottom:30px;'>Cancel</a>
115
- </div>
116
- </div>", $allowed_html);
 
117
  }
118
 
 
119
  public function add_modal_styles()
120
  {
 
121
  $styles = array();
122
  $styles[] = 'display';
123
  $styles[] = 'position';
124
  $styles[] = 'bottom';
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
125
  return $styles;
126
  }
127
  }
5
  */
6
  class Lingotek_Workflow {
7
 
8
+ private $allowed_html = array(
9
+ 'div' => array(
10
+ 'id' => array(),
11
+ 'style' => array(),
12
+ 'class' => array(),
13
+ ),
14
+ 'hr' => array(
15
+ 'width' => array(),
16
+ 'size' => array(),
17
+ ),
18
+ 'h2' => array(
19
+ 'style' => array(),
20
+ ),
21
+ 'br' => array(
22
+ 'class' => array(),
23
+ ),
24
+ 'b' => array(),
25
+ 'p' => array(
26
+ 'id' => array(),
27
+ 'style' => array(),
28
+ ),
29
+ 'a' => array(
30
+ 'id' => array(),
31
+ 'href' => array(),
32
+ 'style' => array(),
33
+ 'class' => array()
34
+ ),
35
+ 'img' => array(
36
+ 'id' => array(),
37
+ 'src' => array(),
38
+ 'style' => array(),
39
+ 'class' => array(),
40
+ ),
41
+ 'span' => array(
42
+ 'id' => array(),
43
+ 'style' => array(),
44
+ 'class' => array(),
45
+ 'ltk-data-tooltip' => array()
46
+ ),
47
+ 'button' => array(
48
+ 'type' => array(),
49
+ 'style' => array(),
50
+ 'class' => array(),
51
+ 'id' => array(),
52
+ 'disabled' => array(),
53
+ ),
54
+ 'table' => array(
55
+ 'class' => array(),
56
+ ),
57
+ 'tbody' => array(
58
+ 'class' => array()
59
+ ),
60
+ 'thead' => array(
61
+ 'class' => array(),
62
+ 'id' => array(),
63
+ ),
64
+ 'tr' => array(
65
+ 'class' => array(),
66
+ 'id' => array(),
67
+ ),
68
+ 'th' => array(
69
+ 'id' => array(),
70
+ 'class' => array(),
71
+ 'style' => array(),
72
+ ),
73
+ 'td' => array(
74
+ 'class' => array()
75
+ ),
76
+ 'ul' => array(
77
+ 'class' => array()
78
+ ),
79
+ 'li' => array(),
80
+ 'input' => array(
81
+ 'id' => array(),
82
+ 'type' => array(),
83
+ 'name' => array(),
84
+ 'value' => array(),
85
+ 'class' => array()
86
+ ),
87
+ );
88
+
89
  /**
90
  * If a modal has already been written to the output buffer then we don't
91
  * want to write it again.
92
  *
93
  * @var boolean
94
  */
95
+ protected static $info_modal_launched = false;
96
 
97
  /**
98
  * If a modal has already been written to the output buffer then we don't
100
  *
101
  * @var boolean
102
  */
103
+ protected static $post_modal_launched = false;
104
+
105
+
106
+ /**
107
+ * If a modal has already been written to the output buffer then we don't
108
+ * want to write it again.
109
+ *
110
+ * @var boolean
111
+ */
112
+ protected static $strings_modal_launched = false;
113
 
114
  /**
115
  * If a modal has already been written to the output buffer then we don't
117
  *
118
  * @var boolean
119
  */
120
+ protected static $terms_modal_launched = false;
121
 
122
  /**
123
+ * If a modal has already been written to the output buffer then we don't
124
+ * want to write it again.
125
  *
126
+ * @var boolean
127
+ */
128
+ protected static $loading_modal_launched = false;
129
+
130
+ /**
131
+ * This flag can be set to keep track of whether
132
+ * the save post action has already occured (for example, if multiple workflow objects are being instantiated and
133
+ * you don't want them to do the same thing twice.)
134
+ *
135
+ * @var boolean
136
+ */
137
+ protected static $save_post_hook_executed = false;
138
+
139
+ /**
140
+ * This flag acts the same as the save_post_hook_executed flag but for terms.
141
+ *
142
+ * @var boolean
143
+ */
144
+ protected static $save_terms_hook_executed = false;
145
+
146
+ /**
147
+ * The workflow_id of the given object.
148
+ *
149
+ * @var string
150
  */
151
+ protected $workflow_id;
152
+
153
+ /**
154
+ * Constructor.
155
+ *
156
+ * @param string $workflow_id
157
+ */
158
+ public function __construct($workflow_id = null) {
159
+ $this->workflow_id = $workflow_id;
160
+ }
161
+
162
 
163
  /**
164
  * Writes a modal to the output buffer. This is called when the Translation > Settings > Defaults pages is loaded.
168
  *
169
  * @param string $id the workflow id.
170
  */
171
+ public function echo_info_modal( $item_id = null, $item_type = null ) {}
172
 
173
  /**
174
  * This method is called when the Posts or Pages columns are being rendered.
175
  *
176
+ * @param string $item_id
177
+ * @param string $wp_locale
178
+ * @param string $item_type
179
  */
180
+ public function echo_posts_modal( $item_id = null, $wp_locale = null, $item_type = null ) {}
181
 
182
  /**
183
  * This method is called when the Terms table is being rendered.
184
  *
185
+ * @param string $item_id
186
+ * @param string $wp_locale
187
+ * @param string $item_type
188
  */
189
+ public function echo_terms_modal( $item_id = null, $wp_locale = null, $item_type = null ) {}
190
+
191
 
192
  /**
193
+ * This method is called when the Strings table is being rendered.
 
194
  *
195
+ * @param string $item_id
196
+ * @param string $wp_locale
197
+ * @param string $item_type
198
+ * @return void
199
+ */
200
+ public function echo_strings_modal( $item_id = null, $wp_locale = null, $item_type = null ) {}
201
+
202
+
203
+
204
+ /**
205
+ * This method is called before a document is uploaded to Lingotek. If the workflow wants to perform an action
206
+ * before a document is uploaded to lingotek it can hook into this action.
207
+ *
208
+ * @param string $item_id
209
+ * @param string $type
210
+ * @return void
211
+ */
212
+ public function pre_upload_to_lingotek($item_id, $type) {}
213
+
214
+ /**
215
+ * Workflows have the option to hook into the save post action. This action is executed
216
+ * BEFORE a document is uploaded to TMS or changed. NOTE: The document may not be uploaded or saved. This
217
+ * method is called when the save post action is triggered.
218
+ *
219
+ * @return void
220
+ */
221
+ public function save_post_hook() {}
222
+
223
+ /**
224
+ * Workflows have the option to hook into the save term action. This action is executed
225
+ * BEFORE a document is uploaded to TMS or changed. NOTE: The document may not be uploaded or saved. This
226
+ * method is called when the save post action is triggered.
227
+ *
228
+ * @return void
229
+ */
230
+ public function save_term_hook() {}
231
+
232
+ /**
233
+ * If a workflow has a custom request procedure then it will not be requested during the standard request_translation
234
+ * or request_translations calls.
235
+ *
236
+ * @return boolean
237
+ */
238
+ public function has_custom_request_procedure() { return false; }
239
+
240
+ /**
241
+ * If a workflow wants to perform a custom request this method will be called after the has_custom_request_procedure() has
242
+ * been called if it returns TRUE. As of now this method (do_custom_request()) only gets called for single requests.
243
+ * bulk requests are ignored if any of the locale items are linked to a workflow that returns true on has_custom_request_procedure().
244
+ *
245
+ * @return void
246
+ */
247
+ public function do_custom_request() { }
248
+
249
+ /**
250
+ * A workflow can override this method and return false if they do not want to support automatic upload upload.
251
+ *
252
+ * @return void
253
  */
254
+ public function auto_upload_allowed() { return true; }
255
+
256
 
257
+ public function get_custom_in_progress_icon() { return false; }
258
  /**
259
  * This method acts as a template for building the modals. The arguments passed
260
  * are inserted into the html string and then echo'd. If any extra html elements
270
  */
271
  add_filter( 'safe_style_css', array(&$this, 'add_modal_styles'));
272
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
273
  $id = isset( $args['id'] ) ? '-' . $args['id'] : '';
274
+ $parent_elements = isset( $args['parent_elements'] ) ? $args['parent_elements'] : '';
275
+ echo wp_kses( "<div id='modal-window-id" . esc_attr( $id ) . "' style='display:none;' >"
276
+ . wp_kses( $parent_elements, $this->allowed_html ) .
277
+ "<div id='modal-body" . esc_attr( $id ) . "' style='height:100%;position: relative;'>" . wp_kses( $args['body'], $this->allowed_html ) . "</div>" .
278
+ // <br>
279
+ // <a id='yes" . esc_attr( $id ) . "' class='lingotek-color dashicons' href='#' style='position:absolute; float:left; bottom:30px;'>Continue</a>
280
+ // <div style='float:right; padding-right:55px;'>
281
+ // <a id='no" . esc_attr( $id ) . "' class='lingotek-color dashicons' href='#' style='position:absolute; float:right; bottom:30px;'>Cancel</a>
282
+ "</div>
283
+ </div>", $this->allowed_html);
284
  }
285
 
286
+
287
  public function add_modal_styles()
288
  {
289
+
290
  $styles = array();
291
  $styles[] = 'display';
292
  $styles[] = 'position';
293
  $styles[] = 'bottom';
294
+ $styles[] = 'margin';
295
+ $styles[] = 'height';
296
+ $styles[] = 'padding-top';
297
+ $styles[] = 'text-align';
298
+ $styles[] = 'font-size';
299
+ $styles[] = 'float';
300
+ $styles[] = 'padding-right';
301
+ $styles[] = 'line-height';
302
+ $styles[] = 'width';
303
+ $styles[] = 'color';
304
+ $styles[] = 'button';
305
+ $styles[] = 'font-style';
306
+ $styles[] = 'font-family';
307
+ $styles[] = 'font-size';
308
+ $styles[] = 'font-weight';
309
+ $styles[] = 'background-color';
310
+ $styles[] = 'border-radius';
311
+ $styles[] = 'background';
312
  return $styles;
313
  }
314
  }
css/workflow/professional-workflow-style.css ADDED
@@ -0,0 +1,1015 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ .ADD-PAYMENT-LATER {
2
+ width: 88px;
3
+ height: 15px;
4
+ /*font-family: Roboto;*/
5
+ font-size: 13px;
6
+ font-weight: 500;
7
+ text-align: center;
8
+ color: rgba(0, 0, 0, 0.58);
9
+ }
10
+
11
+ .ADD-PAYMENT {
12
+ width: 109.3px;
13
+ height: 15px;
14
+ /*font-family: Roboto;*/
15
+ font-size: 13px;
16
+ font-weight: 500;
17
+ text-align: center;
18
+ color: #ffffff;
19
+ }
20
+
21
+ .professional-action-button {
22
+ width: 273px;
23
+ height: 32px;
24
+ border-radius: 3px;
25
+ background-color: #3b9af1;
26
+ box-shadow: 0 2px 3px 0 rgba(0, 0, 0, 0.25);
27
+ border: none;
28
+ }
29
+
30
+ .professional-action-button:hover {
31
+ width: 273px;
32
+ height: 32px;
33
+ border-radius: 3px;
34
+ background-color: rgba(59, 154, 240, 0.82);
35
+ box-shadow: 0 2px 3px 0 rgba(0, 0, 0, 0.25);
36
+ border: none;
37
+ }
38
+
39
+ .prefessional-action-button-default {
40
+ width: 170px;
41
+ height: 32px;
42
+ border-radius: 3px;
43
+ background-color: #3b9af1;
44
+ box-shadow: 0 2px 3px 0 rgba(0, 0, 0, 0.25);
45
+ border: none;
46
+ }
47
+
48
+ .prefessional-action-button-default:hover {
49
+ width: 170px;
50
+ height: 32px;
51
+ border-radius: 3px;
52
+ background-color: rgba(59, 154, 240, 0.82);
53
+ box-shadow: 0 2px 3px 0 rgba(0, 0, 0, 0.26);
54
+ border: none;
55
+ }
56
+
57
+ .professional-action-button-disabled {
58
+ width: 273px;
59
+ height: 32px;
60
+ border-radius: 3px;
61
+ background-color: #ebebeb;
62
+ box-shadow: 0 2px 3px 0 rgba(0, 0, 0, 0.26);
63
+ border: none;
64
+ }
65
+
66
+ .ADD-PAYMENT-DISABLED {
67
+ width: 109.3px;
68
+ height: 15px;
69
+ font-size: 13px;
70
+ font-weight: 500;
71
+ text-align: center;
72
+ color: rgba(0, 0, 0, 0.57);
73
+ }
74
+
75
+ .background-test {
76
+ width: 54px;
77
+ height: 32px;
78
+ border-radius: 3px;
79
+ /*background-color: #ebebeb;*/
80
+ background-color: white;
81
+ /*box-shadow: 0 2px 2px 0 rgba(0, 0, 0, 0.26);*/
82
+ border: none;
83
+ /*background-color: var(--3b9af1);*/
84
+ }
85
+
86
+ .background-test:hover {
87
+ width: 54px;
88
+ height: 32px;
89
+ border-radius: 3px;
90
+ /*background-color: #ebebeb;*/
91
+ background-color: rgba(212, 212, 212, 0.62);
92
+ /*box-shadow: 0 2px 2px 0 rgba(0, 0, 0, 0.26);*/
93
+ border: none;
94
+ }
95
+
96
+ .Upgrade-to-Lingotek {
97
+ width: 477.1px;
98
+ height: 21px;
99
+ /*font-family: Roboto;*/
100
+ font-size: 18px;
101
+ /*text-align: center;*/
102
+ padding-left: 1%;
103
+ color: #ffffff;
104
+ }
105
+
106
+ .header-professional {
107
+ text-align:left;
108
+ padding-left:8px;
109
+ position:absolute;
110
+ padding-top: 15px;
111
+ }
112
+
113
+ .Youve-Selected-Prof {
114
+ padding-left: 1%;
115
+ height: 28px;
116
+ /*font-family: Roboto;*/
117
+ font-size: 24px;
118
+ font-weight: bold;
119
+ color: #000000;
120
+ color: var(--black);
121
+ padding-top: 15px;
122
+ }
123
+
124
+ .By-Selecting-this-op {
125
+ padding-left:1%;
126
+ height: 75px;
127
+ /*font-family: Roboto;*/
128
+ font-size: 16px;
129
+ line-height: 2.06;
130
+ color: #000000;
131
+ color: var(--black);
132
+ width: 85%;
133
+ position: absolute;
134
+ padding-top: 2%;
135
+ left: 0;
136
+ right: 0;
137
+ }
138
+
139
+ .Note-By-using-the- {
140
+ padding-left: 1%;
141
+ width: 65%;
142
+ /*margin: 0 auto;*/
143
+ height: 64px;
144
+ /*font-family: Roboto;*/
145
+ font-size: 14px;
146
+ font-style: italic;
147
+ /*text-align: center;*/
148
+ position: absolute;
149
+ left: 0;
150
+ right: 0;
151
+ bottom: 0;
152
+ padding-bottom: 18%;
153
+ color: rgba(0, 0, 0, 0.57);
154
+ }
155
+
156
+
157
+
158
+
159
+
160
+
161
+ .Congratulations-You {
162
+ width: 490px;
163
+ height: 42px;
164
+ /*font-family: Roboto;*/
165
+ font-size: 18px;
166
+ font-weight: 500;
167
+ color: #000000;
168
+ color: var(--black);
169
+ }
170
+
171
+ .You-can-now-connect {
172
+ width: 95%;
173
+ height: 48px;
174
+ /*font-family: Roboto;*/
175
+ font-size: 14px;
176
+ font-weight: 300;
177
+ color: #000000;
178
+ color: var(--black);
179
+ }
180
+
181
+ .Translation-Request {
182
+ width: 240px;
183
+ height: 19px;
184
+ /*font-family: Roboto;*/
185
+ font-size: 16px;
186
+ text-align: center;
187
+ color: #000000;
188
+ color: var(--black);
189
+ }
190
+
191
+ .Payment-Method {
192
+ width: 153px;
193
+ height: 21px;
194
+ /*font-family: Roboto;*/
195
+ font-size: 18px;
196
+ font-weight: 500;
197
+ padding-top: 10px;
198
+ text-align: center;
199
+ color: #000000;
200
+ color: var(--black);
201
+ }
202
+
203
+ .It-appears-you-haven {
204
+ width: 316px;
205
+ height: 48px;
206
+ /*font-family: Roboto;*/
207
+ font-size: 14px;
208
+ font-weight: 300;
209
+ color: #000000;
210
+ color: var(--black);
211
+ }
212
+
213
+ .Translation-Request-Right {
214
+ width: 251px;
215
+ height: 21px;
216
+ /*font-family: Roboto;*/
217
+ font-size: 18px;
218
+ color: #000000;
219
+ color: var(--black);
220
+ }
221
+
222
+ #table-wrapper {
223
+ width: 95%;
224
+ overflow:hidden;
225
+ overflow-y: auto;
226
+ max-height: 350px;
227
+ }
228
+
229
+ /*#request-table-head {
230
+ position: relative;
231
+ }*/
232
+
233
+ .outer-wrapper {
234
+ position: relative;
235
+ }
236
+
237
+ .request-table {
238
+ width: 100%;
239
+ border-collapse:collapse;
240
+ table-layout: fixed;
241
+ }
242
+
243
+ .request-table-item {
244
+ height: 40px;
245
+ }
246
+
247
+ .table-header {
248
+ /*width: 25px;*/
249
+ height: 14px;
250
+ /*font-family: Roboto;*/
251
+ font-size: 12px;
252
+ font-weight: 500;
253
+ text-align: center;
254
+ color: #000000;
255
+ color: var(--black);
256
+ }
257
+
258
+ .table-total {
259
+ display: table-cell; text-align: center;
260
+ background-color: rgba(243, 243, 243, 0.52);
261
+ }
262
+
263
+ .row-total {
264
+ background-color: rgba(243, 243, 243, 0.52);
265
+ }
266
+
267
+ .bordered-bottom {
268
+ border-bottom: solid 1px rgba(0, 0, 0, 0.12) !important;
269
+ }
270
+
271
+ .translation-summary-list-text {
272
+ width: 262px;
273
+ height: 14px;
274
+ /*font-family: Roboto;*/
275
+ font-size: 12px;
276
+ font-weight: 300;
277
+ color: #000000 !important;
278
+ /*color: var(--black) !important;*/
279
+ }
280
+
281
+ .translation-summary-list {
282
+ list-style-type:disc;
283
+ padding-left: 30px;
284
+ color:#ec8225;
285
+ max-height: 20%;
286
+ overflow: auto;
287
+ }
288
+
289
+ .translation-summary-cost {
290
+ float: right;
291
+ padding-right: 3%;
292
+ }
293
+
294
+ .request-total {
295
+ padding-left:15px;
296
+ font-size: 14px;
297
+ font-weight: 300;
298
+ }
299
+
300
+ .lingotek-total-amount {
301
+ font-size: 22px;
302
+ font-weight: 500;
303
+ }
304
+
305
+ .disclaimer-request {
306
+ width: 90%;
307
+ height: 33px;
308
+ /* font-family: Roboto; */
309
+ font-size: 9px;
310
+ padding-left: 5%;
311
+ color: rgba(0, 0, 0, 0.57);
312
+ text-align: center;
313
+ position: absolute;
314
+ bottom: 12%;
315
+ }
316
+
317
+ .ltk-request-payment-disclaimer {
318
+ width: 90%;
319
+ height: 33px;
320
+ /* font-family: Roboto; */
321
+ font-size: 9px;
322
+ padding-left: 5%;
323
+ color: rgba(0, 0, 0, 0.57);
324
+ text-align: center;
325
+ position: absolute;
326
+ bottom: 6%;
327
+ }
328
+
329
+ .request-checkbox {
330
+ /*padding-left: 10px;*/
331
+ padding-left: 7%;
332
+ position: absolute;
333
+ bottom: 14%;
334
+ }
335
+
336
+ .terms-conditions {
337
+ width: 189px;
338
+ height: 11px;
339
+ /*font-family: Roboto;*/
340
+ font-size: 11px;
341
+ /*color: #3085ed;*/
342
+ }
343
+
344
+ .header-table-hidden {
345
+ display: none;
346
+ }
347
+
348
+ .row-table-hidden {
349
+ display: none;
350
+ }
351
+
352
+ .row-total {
353
+ text-align: center;
354
+ }
355
+
356
+ .document-title {
357
+ /*max-width: 70px;*/
358
+ text-overflow: ellipsis;
359
+ overflow: hidden;
360
+ white-space: nowrap;
361
+ text-align: center;
362
+ }
363
+
364
+ .loading-progress-bar-outer {
365
+ position:absolute;
366
+ left:0; right:0;
367
+ top:0; bottom:0;
368
+ margin:auto;
369
+ width: 350px;
370
+ height: 30px;
371
+ border: solid 1px #57554f;
372
+ }
373
+
374
+ .loading-progress-bar-inner {
375
+ width: 210px;
376
+ height: 30px;
377
+ background-color: #57554f;
378
+ }
379
+
380
+ .loading-progress-percent {
381
+ position:absolute;
382
+ left:400px; right:0;
383
+ top:0; bottom:0;
384
+ margin:auto;
385
+ width: 214.2px;
386
+ height: 16px;
387
+ font-size: 14px;
388
+ font-weight: 500;
389
+ text-align: center;
390
+ color: #000000;
391
+ }
392
+
393
+ .loading-translations-image {
394
+ position:absolute;
395
+ left:0; right:0;
396
+ top:0; bottom:330px;
397
+ margin:auto;
398
+ }
399
+
400
+ .Analyzing-translations {
401
+ position:absolute;
402
+ left:0; right:0;
403
+ top:260px; bottom:0;
404
+ margin:auto;
405
+ width: 367px;
406
+ height: 21px;
407
+ font-size: 18px;
408
+ font-weight: 300;
409
+ text-align: center;
410
+ color: #000000;
411
+ }
412
+
413
+ .payment-portal-image {
414
+ padding-top: 20px;
415
+ position:absolute;
416
+ left:0; right:0;
417
+ top:0;
418
+ margin:auto;
419
+ }
420
+
421
+ .You-are-now-being-re {
422
+ position:absolute;
423
+ left:0; right:0;
424
+ bottom:0;
425
+ margin:auto;
426
+ padding-bottom: 75px;
427
+ width: 565px;
428
+ height: 21px;
429
+ font-size: 18px;
430
+ font-weight: 300;
431
+ text-align: center;
432
+ color: #000000;
433
+ }
434
+
435
+ .payment-portal-loading {
436
+ position:absolute;
437
+ left:0; right:0;
438
+ top:0; bottom:0;
439
+ margin:auto;
440
+ padding-top: 20px;
441
+ }
442
+
443
+ #words-column {
444
+ text-align: center;
445
+ }
446
+ .word-count {
447
+ text-align: center;
448
+ }
449
+
450
+ #wrapper {
451
+ margin-right: 320px;
452
+ }
453
+ #content {
454
+ float: left;
455
+ width: 100%;
456
+ }
457
+ #sidebar {
458
+ position: relative;
459
+ float: right;
460
+ width: 320px;
461
+ margin-right: -320px;
462
+ padding-top: 10px;
463
+ }
464
+ #cleared {
465
+ clear: both;
466
+ }
467
+
468
+ .terms-and-conditions-header {
469
+ width: 472px;
470
+ height: 21px;
471
+ font-size: 18px;
472
+ font-weight: 500;
473
+ text-align: center;
474
+ color: #000000;
475
+ }
476
+
477
+ #close-terms-and-conditions {
478
+ width: 54px;
479
+ height: 32px;
480
+ border-radius: 3px;
481
+ background-color: #f13b3b;
482
+ border: none;
483
+ box-shadow: 0 2px 4px 0 rgba(0, 0, 0, 0.26);
484
+ position: absolute;
485
+ bottom: 0;
486
+ left: 0;
487
+ right: 0;
488
+ margin: auto;
489
+ }
490
+ #close-terms-and-conditions:hover {
491
+ width: 54px;
492
+ height: 32px;
493
+ border-radius: 3px;
494
+ background-color: rgba(238, 32, 40, 0.8);
495
+ border: none;
496
+ box-shadow: 0 2px 4px 0 rgba(0, 0, 0, 0.26);
497
+ position: absolute;
498
+ bottom: 0;
499
+ left: 0;
500
+ right: 0;
501
+ margin: auto;
502
+ }
503
+
504
+ #terms-of-service-loading-ltk {
505
+ padding-left: 23%;
506
+ padding-top: 7%;
507
+ }
508
+
509
+ .float-bottom-right {
510
+ float: right;
511
+ position: absolute;
512
+ bottom: 0;
513
+ /* left: 0; */
514
+ right: 0;
515
+ margin: auto;
516
+ }
517
+
518
+ .float-bottom-left {
519
+ float: left;
520
+ position: absolute;
521
+ bottom: 0;
522
+ /* left: 0; */
523
+ left: 0;
524
+ margin: auto;
525
+ }
526
+
527
+ .float-bottom-right-next-to {
528
+ float: right;
529
+ position: absolute;
530
+ bottom: 0;
531
+ right: 11%;
532
+ margin: auto;
533
+ }
534
+
535
+ .float-bottom-right-next-to-default {
536
+ float: right;
537
+ position: absolute;
538
+ bottom: 0;
539
+ right: 23%;
540
+ margin: auto;
541
+ }
542
+
543
+
544
+ .float-center {
545
+ margin: 0 auto;
546
+ right: 0;
547
+ position: absolute;
548
+ left: 0;
549
+ bottom: 0;
550
+ }
551
+
552
+ .CLOSE-TERMS-CONDITIONS {
553
+ width: 80.8px;
554
+ height: 15px;
555
+ font-size: 13px;
556
+ font-weight: 500;
557
+ text-align: center;
558
+ color: #ffffff;
559
+ }
560
+
561
+ #professional-terms-and-conditions {
562
+ position: relative;
563
+ width: 95%;
564
+ }
565
+
566
+ .terms-and-conditions-content {
567
+ font-size: 14px;
568
+ font-weight: 300;
569
+ color: #000000;
570
+ max-height: 400px;
571
+ overflow-y:auto
572
+ }
573
+
574
+ #payment-portal-wrapper {
575
+ height: 100%;
576
+ position: relative;
577
+ }
578
+
579
+ .professional-card-border {
580
+ width: 271px;
581
+ height: 35px;
582
+ border: solid 1px #3b9af1;
583
+ position: relative;
584
+ }
585
+
586
+ .credit-card-header {
587
+ width: 113px;
588
+ height: 16px;
589
+ font-size: 14px;
590
+ color: #000000;
591
+ }
592
+
593
+ #last-four-digits {
594
+ width: 37px;
595
+ height: 18px;
596
+ font-size: 15px;
597
+ font-weight: 500;
598
+ color: #000000;
599
+
600
+ position: relative;
601
+ top: 25%;
602
+ transform: translateY(-50%);
603
+ }
604
+
605
+
606
+ .credit-card-dots-div {
607
+ float: left;
608
+ padding-right: 5px;
609
+ height: 100%;
610
+ width: 150px;
611
+ padding-right: 3px;
612
+ padding-left: 3px;
613
+ }
614
+
615
+ .credit-card-image-div {
616
+ width: 17%;
617
+ height: 100%;
618
+ float: left;
619
+ }
620
+
621
+ #credit-card-image {
622
+ width: 50%;
623
+ padding-left: 23%;
624
+ padding-top: 22%;
625
+ }
626
+
627
+ #credit-card-dots {
628
+ position: relative;
629
+ top: 25%;
630
+ transform: translateY(-50%);
631
+ width: 100%;
632
+ }
633
+
634
+ #blue-radio-button {
635
+ position: relative;
636
+ top: 50%;
637
+ transform: translateY(-50%);
638
+ }
639
+
640
+ .last-four-digits-div {
641
+ float: left;
642
+ height: 100%;
643
+ padding-left: 5px;
644
+ }
645
+
646
+
647
+ .blue-radio-button-div {
648
+ float: left;
649
+ padding-right: 5px;
650
+ padding-left: 5px;
651
+ height: 100%;
652
+ }
653
+
654
+
655
+ .professional-translation-view-invoice {
656
+ position: relative;
657
+ left: 0;
658
+ right: 0;
659
+ margin: auto;
660
+ bottom: 0;
661
+ top: 70%;
662
+ width: 440.2px;
663
+ height: 38px;
664
+ font-size: 18px;
665
+ font-weight: 300;
666
+ text-align: center;
667
+ color: #000000;
668
+ }
669
+
670
+ #professional-translation-cost-success {
671
+ font-size: 20px;
672
+ font-weight: bold;
673
+ }
674
+
675
+ #requesting-translation-success-screen {
676
+ position: absolute;
677
+ width: 100%;
678
+ height: 100%;
679
+ }
680
+
681
+ #requesting-translation-error-screen {
682
+ position: absolute;
683
+ width: 100%;
684
+ height: 100%;
685
+ }
686
+
687
+ .professional-view-invoice-btn {
688
+ position: absolute;
689
+ top: 92%;
690
+ width: 105px;
691
+ height: 32px;
692
+ border-radius: 3px;
693
+ background-color: #3b9af1;
694
+ border: none;
695
+ box-shadow: 0 2px 3px 0 rgba(0, 0, 0, 0.26);
696
+ }
697
+
698
+ .professional-view-invoice-btn:hover {
699
+ position: absolute;
700
+ top: 92%;
701
+ width: 105px;
702
+ height: 32px;
703
+ border-radius: 3px;
704
+ background-color: rgba(59, 154, 240, 0.82);
705
+ border: none;
706
+ box-shadow: 0 2px 3px 0 rgba(0, 0, 0, 0.26);
707
+ }
708
+
709
+ .green-check-success {
710
+ position: absolute;
711
+ left: 0;
712
+ right: 0;
713
+ top: 0;
714
+ bottom: 0;
715
+ margin: auto;
716
+ }
717
+
718
+ .professional-upload-warning-header {
719
+ font-size: 20px;
720
+ font-weight: 300;
721
+ text-align: center;
722
+ color: #000000;
723
+ }
724
+
725
+ .professional-upload-warning-body {
726
+ font-size: 16px;
727
+ font-weight: 300;
728
+ line-height: 2.06;
729
+ color: #000000;
730
+ }
731
+
732
+ .professional-upload-warning-header-container {
733
+ left: 0;
734
+ right: 0;
735
+ margin: auto;
736
+ width: 707px;
737
+ height: 24px;
738
+ position: absolute;
739
+ top: 5%;
740
+ }
741
+
742
+ .professional-upload-warning-body-container {
743
+ left: 0;
744
+ right: 0;
745
+ margin: auto;
746
+ width: 707px;
747
+ height: 99px;
748
+ position: absolute;
749
+ top: 20%;
750
+ }
751
+
752
+ .professional-warning-checkbox-container {
753
+ left: 0;
754
+ right: 0;
755
+ margin: auto;
756
+ width: 707px;
757
+ position: absolute;
758
+ top: 58%;
759
+ }
760
+ .professional-warning-checkbox-text-container {
761
+ left: 0;
762
+ right: 20%;
763
+ margin: auto;
764
+ width: 707px;
765
+ position: absolute;
766
+ top: 58%;
767
+ width: 460.1px;
768
+ height: 57px;
769
+ }
770
+ .professional-warning-checkbox-text {
771
+ font-size: 16px;
772
+ color: rgba(0, 0, 0, 0.58);
773
+ }
774
+
775
+ .professional-cancel-button {
776
+ width: 63px;
777
+ height: 32px;
778
+ border-radius: 3px;
779
+ background-color: white;
780
+ /*box-shadow: 0 2px 4px 0 rgba(0, 0, 0, 0.26);*/
781
+ border: none;
782
+ }
783
+
784
+ .professional-cancel-button:hover {
785
+ width: 63px;
786
+ height: 32px;
787
+ border-radius: 3px;
788
+ background-color: rgba(212, 212, 212, 0.62);
789
+ border: none;
790
+ }
791
+
792
+ .professional-okay-warning-button {
793
+ width: 73px;
794
+ height: 32px;
795
+ border-radius: 3px;
796
+ background-color: #F13B3B;
797
+ box-shadow: 0 2px 3px 0 rgba(0, 0, 0, 0.26);
798
+ border: none;
799
+ }
800
+
801
+ .professional-okay-warning-button:hover {
802
+ width: 73px;
803
+ height: 32px;
804
+ border-radius: 3px;
805
+ background-color: rgba(238, 32, 40, 0.8);
806
+ box-shadow: 0 2px 3px 0 rgba(0, 0, 0, 0.26);
807
+ border: none;
808
+ }
809
+
810
+
811
+
812
+ .professional-okay-warning-button-disabled {
813
+ width: 73px;
814
+ height: 32px;
815
+ border-radius: 3px;
816
+ background-color: #e6e6e6;
817
+ box-shadow: 0 2px 3px 0 rgba(0, 0, 0, 0.26);
818
+ border: none;
819
+ }
820
+
821
+ .minimum-per-language-warning {
822
+ width: 100%;
823
+ height: 15px;
824
+ /*font-family: Roboto;*/
825
+ font-size: 13px;
826
+ }
827
+
828
+ .minimum-warning {
829
+ color: #ff7f00;
830
+ }
831
+
832
+ .minimum-disclaimer {
833
+ font-size: 10px;
834
+ font-weight: 300;
835
+ font-style: italic;
836
+ color: #666666;
837
+ padding-left: 5%;
838
+ }
839
+
840
+ .delivery-estimation {
841
+ height: 16px;
842
+ /* font-family: Roboto; */
843
+ font-size: 14px;
844
+ font-weight: 300;
845
+ color: #000000;
846
+ position: absolute;
847
+ bottom: 21%;
848
+ padding-left: 7%;
849
+ }
850
+
851
+ .business-days {
852
+ font-size: 14px;
853
+ font-weight: 500;
854
+ color: #000000;
855
+ }
856
+
857
+ .language-header {
858
+ font-size: 10px;
859
+ /*font-weight:normal;*/
860
+ }
861
+
862
+ .cost-header {
863
+ font-size: 11px;
864
+ font-weight:normal;
865
+ }
866
+
867
+ .cost-font-size {
868
+ font-size: 11px;
869
+ }
870
+
871
+ .invisible {
872
+ display: none !important;
873
+ }
874
+
875
+ .ltk-thickbox {
876
+ width: 980px !important;
877
+ margin-left: -490px !important;
878
+ margin-top: -295px !important;
879
+ visibility: visible !important;
880
+ }
881
+
882
+ .ltk-thickbox-warning {
883
+ margin-left: -415px !important;
884
+ width: 830px !important;
885
+ margin-top: -220px !important;
886
+ visibility: visible !important;
887
+ }
888
+
889
+
890
+ /* Add this attribute to the element that needs a tooltip */
891
+ [ltk-data-tooltip] {
892
+ position: relative;
893
+ z-index: 2;
894
+ cursor: pointer;
895
+ }
896
+
897
+ /* Hide the tooltip content by default */
898
+ [ltk-data-tooltip]:before,
899
+ [ltk-data-tooltip]:after {
900
+ visibility: hidden;
901
+ -ms-filter: "progid:DXImageTransform.Microsoft.Alpha(Opacity=0)";
902
+ filter: progid: DXImageTransform.Microsoft.Alpha(Opacity=0);
903
+ opacity: 0;
904
+ pointer-events: none;
905
+ }
906
+
907
+ /* Position tooltip above the element */
908
+ [ltk-data-tooltip]:before {
909
+ position: absolute;
910
+ bottom: 150%;
911
+ left: 50%;
912
+ margin-bottom: 5px;
913
+ margin-left: -200px;
914
+ padding: 7px;
915
+ width: 236px;
916
+ -webkit-border-radius: 3px;
917
+ -moz-border-radius: 3px;
918
+ border-radius: 3px;
919
+ background-color: #000;
920
+ background-color: hsla(0, 0%, 20%, 0.9);
921
+ color: #fff;
922
+ content: attr(ltk-data-tooltip);
923
+ text-align: center;
924
+ font-size: 14px;
925
+ line-height: 1.2;
926
+ }
927
+
928
+ /* Triangle hack to make tooltip look like a speech bubble */
929
+ [ltk-data-tooltip]:after {
930
+ position: absolute;
931
+ bottom: 150%;
932
+ left: 50%;
933
+ margin-left: -5px;
934
+ width: 0;
935
+ border-top: 5px solid #000;
936
+ border-top: 5px solid hsla(0, 0%, 20%, 0.9);
937
+ border-right: 5px solid transparent;
938
+ border-left: 5px solid transparent;
939
+ content: " ";
940
+ font-size: 0;
941
+ line-height: 0;
942
+ }
943
+
944
+ /* Show tooltip content on hover */
945
+ [ltk-data-tooltip]:hover:before,
946
+ [ltk-data-tooltip]:hover:after {
947
+ visibility: visible;
948
+ -ms-filter: "progid:DXImageTransform.Microsoft.Alpha(Opacity=100)";
949
+ filter: progid: DXImageTransform.Microsoft.Alpha(Opacity=100);
950
+ opacity: 1;
951
+ }
952
+
953
+ /*centered*/
954
+
955
+ [ltk-data-tooltip-ctr] {
956
+ position: relative;
957
+ z-index: 2;
958
+ cursor: pointer;
959
+ }
960
+
961
+ /* Hide the tooltip content by default */
962
+ [ltk-data-tooltip-ctr]:before,
963
+ [ltk-data-tooltip-ctr]:after {
964
+ visibility: hidden;
965
+ -ms-filter: "progid:DXImageTransform.Microsoft.Alpha(Opacity=0)";
966
+ filter: progid: DXImageTransform.Microsoft.Alpha(Opacity=0);
967
+ opacity: 0;
968
+ pointer-events: none;
969
+ }
970
+
971
+ /* Position tooltip above the element */
972
+ [ltk-data-tooltip-ctr]:before {
973
+ position: absolute;
974
+ bottom: 150%;
975
+ left: 50%;
976
+ margin-bottom: 5px;
977
+ margin-left: -130px;
978
+ padding: 7px;
979
+ width: 236px;
980
+ -webkit-border-radius: 3px;
981
+ -moz-border-radius: 3px;
982
+ border-radius: 3px;
983
+ background-color: #000;
984
+ background-color: hsla(0, 0%, 20%, 0.9);
985
+ color: #fff;
986
+ content: attr(ltk-data-tooltip-ctr);
987
+ text-align: center;
988
+ font-size: 14px;
989
+ line-height: 1.2;
990
+ }
991
+
992
+ /* Triangle hack to make tooltip look like a speech bubble */
993
+ [ltk-data-tooltip-ctr]:after {
994
+ position: absolute;
995
+ bottom: 150%;
996
+ left: 50%;
997
+ margin-left: -5px;
998
+ width: 0;
999
+ border-top: 5px solid #000;
1000
+ border-top: 5px solid hsla(0, 0%, 20%, 0.9);
1001
+ border-right: 5px solid transparent;
1002
+ border-left: 5px solid transparent;
1003
+ content: " ";
1004
+ font-size: 0;
1005
+ line-height: 0;
1006
+ }
1007
+
1008
+ /* Show tooltip content on hover */
1009
+ [ltk-data-tooltip-ctr]:hover:before,
1010
+ [ltk-data-tooltip-ctr]:hover:after {
1011
+ visibility: visible;
1012
+ -ms-filter: "progid:DXImageTransform.Microsoft.Alpha(Opacity=100)";
1013
+ filter: progid: DXImageTransform.Microsoft.Alpha(Opacity=100);
1014
+ opacity: 1;
1015
+ }
error.log ADDED
File without changes
img/blue-radio-button.svg ADDED
@@ -0,0 +1,15 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+ <svg width="18px" height="18px" viewBox="0 0 18 18" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
3
+ <!-- Generator: Sketch 43.2 (39069) - http://www.bohemiancoding.com/sketch -->
4
+ <title>ic_radio_button_checked_black_24px (1)</title>
5
+ <desc>Created with Sketch.</desc>
6
+ <defs></defs>
7
+ <g id="wp-translation" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
8
+ <g id="Terms-and-Conditions" transform="translate(-1124.000000, -396.000000)">
9
+ <g id="ic_radio_button_checked_black_24px-(1)" transform="translate(1123.000000, 395.000000)">
10
+ <path d="M10,5.83333333 C7.7,5.83333333 5.83333333,7.7 5.83333333,10 C5.83333333,12.3 7.7,14.1666667 10,14.1666667 C12.3,14.1666667 14.1666667,12.3 14.1666667,10 C14.1666667,7.7 12.3,5.83333333 10,5.83333333 Z M10,1.66666667 C5.4,1.66666667 1.66666667,5.4 1.66666667,10 C1.66666667,14.6 5.4,18.3333333 10,18.3333333 C14.6,18.3333333 18.3333333,14.6 18.3333333,10 C18.3333333,5.4 14.6,1.66666667 10,1.66666667 Z M10,16.6666667 C6.31666667,16.6666667 3.33333333,13.6833333 3.33333333,10 C3.33333333,6.31666667 6.31666667,3.33333333 10,3.33333333 C13.6833333,3.33333333 16.6666667,6.31666667 16.6666667,10 C16.6666667,13.6833333 13.6833333,16.6666667 10,16.6666667 Z" id="Shape" fill="#2196F3" fill-rule="nonzero"></path>
11
+ <polygon id="Shape" points="0 0 20 0 20 20 0 20"></polygon>
12
+ </g>
13
+ </g>
14
+ </g>
15
+ </svg>
img/checkmark-green.svg ADDED
@@ -0,0 +1,18 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+ <svg width="100px" height="100px" viewBox="0 0 100 100" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
3
+ <!-- Generator: Sketch 43.2 (39069) - http://www.bohemiancoding.com/sketch -->
4
+ <title>checkmark</title>
5
+ <desc>Created with Sketch.</desc>
6
+ <defs></defs>
7
+ <g id="Page-1" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
8
+ <g id="Payment-Complete-Modal" transform="translate(-757.000000, -372.000000)">
9
+ <g id="checkmark" transform="translate(757.000000, 372.000000)">
10
+ <circle id="background" fill="#15D777" cx="50" cy="50" r="50"></circle>
11
+ <g id="check-mark-svg" transform="translate(18.000000, 17.000000)">
12
+ <polygon id="Shape" points="0 0 65 0 65 65 0 65"></polygon>
13
+ <polygon id="Shape" fill="#FFFFFF" fill-rule="nonzero" points="24.375 43.79375 13.08125 32.5 9.23541667 36.31875 24.375 51.4583333 56.875 18.9583333 53.05625 15.1395833"></polygon>
14
+ </g>
15
+ </g>
16
+ </g>
17
+ </g>
18
+ </svg>
img/credit-cards/alipay.svg ADDED
@@ -0,0 +1,11 @@
 
 
 
 
 
 
 
 
 
 
 
1
+ <svg xmlns="http://www.w3.org/2000/svg" width="750" height="471" viewBox="0 0 750 471">
2
+ <g fill="none" fill-rule="evenodd">
3
+ <rect width="750" height="471" fill="#FFFFFF" rx="40"/>
4
+ <path fill="#2BA6DF" d="M99.460353,243.349396 C94.6592864,243.949379 86.2574197,245.749327 81.456353,249.949206 C67.053153,262.548841 75.4550197,284.7482 104.861553,284.7482 C121.665286,284.7482 138.46902,273.948512 151.671953,257.148997 C132.467686,248.149258 116.86422,241.549448 99.460353,243.349396 L99.460353,243.349396 Z"/>
5
+ <path fill="#2BA6DF" d="M207.034,258.796653 C234.04,267.796393 240.041333,268.396375 240.041333,268.396375 L240.041333,172.39915 C240.041333,156.199618 226.8384,143 210.034667,143 L84.0066667,143 C67.8030667,143 54,156.199618 54,172.39915 L54,298.395508 C54,314.59504 67.2029333,327.794658 84.0066667,327.794658 L210.034667,327.794658 C226.238267,327.794658 240.041333,314.59504 240.041333,298.395508 L240.041333,297.195543 C240.041333,297.195543 192.030667,277.396115 167.4252,265.396462 C151.2216,285.19589 130.216933,297.795525 108.012,297.795525 C70.8037333,297.795525 58.2009333,265.396462 76.2049333,244.397069 C79.8057333,239.597208 86.4072,235.397329 96.6094667,232.997399 C112.212933,229.397503 137.418533,235.397329 160.823733,243.197104 C165.024667,235.397329 168.625467,226.997572 171.026,217.997832 L98.4098667,217.997832 L98.4098667,210.79804 L135.618133,210.79804 L135.618133,196.398456 L90.008,196.398456 L90.008,189.198665 L135.618133,189.198665 L135.618133,170.599202 C135.618133,170.599202 135.618133,167.599289 138.6188,167.599289 L156.6228,167.599289 L156.6228,189.798647 L201.6328,189.798647 L201.6328,196.398456 L156.6228,196.398456 L156.6228,209.598075 L193.230933,209.598075 C189.630133,223.997659 184.228933,237.197277 177.627467,248.596948 C189.630133,252.796826 199.8324,256.396722 207.034,258.796653 L207.034,258.796653 Z"/>
6
+ <path fill="#3F3A39" d="M325.688933 186.612532L365.297733 272.410052 344.293067 272.410052 333.490667 249.610711 301.083467 249.610711 290.281067 272.410052 276.478 272.410052 316.686933 189.012463C316.686933 189.012463 317.8872 186.612532 320.287733 186.612532 322.088133 186.612532 325.688933 186.612532 325.688933 186.612532L325.688933 186.612532zM304.684267 241.810937L329.889867 241.810937 317.287067 214.811717 304.684267 241.810937 304.684267 241.810937zM392.132267 273.092791L372.928 273.092791 372.928 191.49515C372.928 189.095219 374.128267 187.895254 377.128933 187.895254L392.132267 187.895254 392.132267 273.092791 392.132267 273.092791zM428.140267 272.534187L408.936 272.534187 408.936 210.735973C408.936 208.336042 410.136267 207.136077 413.136933 207.136077L428.140267 207.136077 428.140267 272.534187 428.140267 272.534187zM451.621934 208.418799L464.224734 208.418799 464.224734 214.418625C466.625267 212.618677 469.025801 210.818729 472.026467 210.218747 475.027134 209.018781 478.027801 208.418799 482.228734 208.418799 486.429667 208.418799 490.030467 209.018781 493.031134 210.818729 496.631934 212.618677 499.032467 214.418625 501.433001 217.418539 503.833534 220.418452 505.633934 223.418365 506.834201 227.018261 508.034467 230.618157 508.634601 234.218053 508.634601 238.417932 508.634601 243.817775 508.034467 248.617637 506.234067 252.817515 504.433667 257.017394 502.633267 261.217272 499.632601 264.217186 496.631934 267.217099 493.631267 270.217012 489.430334 272.01696 485.229401 273.816908 481.028467 274.416891 476.227401 274.416891L469.625934 274.416891C467.825534 274.416891 466.025134 273.816908 464.224734 273.216926L464.224734 294.816301 445.020467 294.816301 445.020467 216.218573C444.420334 208.418799 447.421001 208.418799 451.621934 208.418799L451.621934 208.418799zM464.224734 255.217446C464.224734 257.017394 464.224734 258.217359 464.824867 259.417325 465.425001 260.61729 466.025134 261.817255 467.225401 263.01722 468.425667 264.217186 469.625934 264.817168 470.826201 265.417151 472.026467 266.017134 473.826867 266.017134 475.627267 266.017134 477.427667 266.017134 478.627934 265.417151 480.428334 264.217186 481.628601 263.01722 483.429001 261.817255 484.029134 259.417325 484.629267 257.017394 485.829534 255.217446 486.429667 252.217533 487.029801 249.217619 487.629934 246.817689 487.629934 243.217793 487.629934 239.017914 487.629934 235.418018 487.029801 232.418105 486.429667 229.418192 485.829534 227.018261 484.629267 224.61833 483.429001 222.818382 482.228734 221.018434 481.028467 219.818469 479.828201 218.618504 478.027801 218.018521 476.227401 218.018521 475.027134 218.018521 473.826867 218.018521 472.626601 218.618504 471.426334 219.218486 470.226067 219.818469 469.625934 220.418452 468.425667 221.018434 467.825534 222.2184 466.625267 222.818382 465.425001 224.018348 464.824867 224.61833 464.224734 225.818296L464.224734 255.217446 464.224734 255.217446zM545.252 208.418799C550.053067 208.418799 553.653867 209.018781 557.254667 209.618764 560.255333 210.218747 563.256 211.418712 565.656533 213.21866 568.057067 215.018608 569.257333 216.818556 570.4576 218.618504 571.657867 221.018434 572.258 223.418365 572.258 225.818296L572.258 273.216926 553.053733 273.216926 553.053733 268.417064C551.853467 269.61703 550.6532 270.217012 550.053067 270.816995 548.8528 271.416978 547.652533 272.01696 546.452267 272.616943 545.252 273.216926 544.051733 273.816908 542.251333 273.816908 540.450933 274.416891 538.650533 274.416891 536.850133 274.416891 533.849467 274.416891 531.448933 273.816908 529.0484 273.216926 526.647867 272.616943 524.847467 271.416978 523.047067 269.61703 521.246667 268.417064 520.0464 266.617116 519.446267 264.217186 518.846133 262.417238 518.246 260.017307 518.246 257.617377 518.246 255.217446 518.846133 252.817515 519.446267 251.017567 520.0464 249.217619 521.8468 247.417671 523.047067 245.617723 524.247333 243.817775 526.647867 242.61781 528.448267 241.417845 530.8488 240.217879 532.6492 239.017914 535.649867 237.817949 538.0504 236.617984 540.450933 236.018001 543.4516 234.818036 545.852133 234.218053 548.8528 233.018088 551.253333 232.418105L553.653867 231.818122 553.653867 225.218313C553.653867 223.418365 553.653867 221.618417 553.053733 219.818469 552.4536 218.618504 551.853467 217.418539 551.253333 216.218573 550.6532 215.618591 549.452933 214.418625 548.8528 214.418625 547.652533 213.818643 546.452267 213.818643 545.252 213.818643 545.252 213.818643 535.049733 213.818643 526.047733 221.618417L521.8468 215.018608C520.0464 216.218573 530.8488 208.418799 545.252 208.418799L545.252 208.418799zM551.853467 240.217879C550.053067 240.817862 548.252667 242.017827 546.452267 243.217793 544.651867 244.417758 542.851467 245.617723 541.051067 246.817689 539.250667 248.017654 538.0504 249.217619 537.450267 251.017567 536.25 252.217533 536.25 254.017481 536.25 255.217446 536.25 256.417411 536.25 257.617377 536.850133 258.817342 537.450267 260.017307 537.450267 260.61729 538.0504 261.817255 538.650533 263.01722 539.250667 263.01722 539.8508 263.617203 540.450933 264.217186 541.051067 264.217186 542.251333 264.217186 544.051733 264.217186 545.252 263.617203 547.0524 263.01722 548.8528 261.817255 550.6532 260.61729 552.4536 259.417325L552.4536 240.217879 551.853467 240.217879zM598.406667 294.216319L585.803867 294.216319 585.203733 282.816648C585.203733 282.816648 600.8072 283.416631 605.608267 277.416804 607.408667 275.016874 608.608933 268.417064 608.608933 268.417064L577.402 208.418799 598.406667 208.418799 618.211067 247.417671 635.614933 208.418799 649.418 208.418799 617.610933 279.216752C616.410667 281.616683 611.6096 294.216319 598.406667 294.216319L598.406667 294.216319z"/>
7
+ <ellipse cx="418.602" cy="189.5" fill="#2BA6DF" rx="9.602" ry="8.5"/>
8
+ <path fill="#3F3A39" d="M668.879 158.31L662.278 158.31 662.278 157.11 676.681 157.11 676.681 158.31 670.08 158.31 670.08 176.909 668.279 176.909 668.279 158.31z"/>
9
+ <path fill="#3F3A39" d="M679.596133,157.109937 L681.996667,157.109937 L686.1976,168.509607 L687.998,172.709486 L687.998,172.709486 C688.598133,171.509521 689.198267,169.709573 689.7984,168.509607 L693.999333,157.109937 L696.399867,157.109937 L696.399867,177.509347 L693.999333,177.509347 L693.999333,164.909712 L693.999333,159.509868 L693.999333,159.509868 L692.198933,164.309729 L687.998,176.309382 L686.797733,176.309382 L682.5968,164.309729 L680.7964,159.509868 L680.7964,159.509868 L680.7964,164.909712 L680.7964,177.509347 L678.996,177.509347 L678.996,157.109937 L679.596133,157.109937 Z"/>
10
+ </g>
11
+ </svg>
img/credit-cards/amex.svg ADDED
@@ -0,0 +1,14 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?xml version="1.0" encoding="UTF-8" standalone="no"?>
2
+ <svg width="752px" height="471px" viewBox="0 0 752 471" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:sketch="http://www.bohemiancoding.com/sketch/ns">
3
+ <!-- Generator: Sketch 3.3.1 (12005) - http://www.bohemiancoding.com/sketch -->
4
+ <title>Slice 1</title>
5
+ <desc>Created with Sketch.</desc>
6
+ <defs></defs>
7
+ <g id="Page-1" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd" sketch:type="MSPage">
8
+ <g id="amex" sketch:type="MSLayerGroup">
9
+ <rect id="Rectangle-1" fill="#2557D6" sketch:type="MSShapeGroup" x="1" y="0" width="750" height="471" rx="40"></rect>
10
+ <path d="M1.002688,221.18508 L37.026849,221.18508 L45.149579,201.67506 L63.334596,201.67506 L71.436042,221.18508 L142.31637,221.18508 L142.31637,206.26909 L148.64322,221.24866 L185.43894,221.24866 L191.76579,206.04654 L191.76579,221.18508 L367.91701,221.18508 L367.83451,189.15941 L371.2427,189.15941 C373.62924,189.24161 374.3263,189.46144 374.3263,193.38516 L374.3263,221.18508 L465.43232,221.18508 L465.43232,213.72973 C472.78082,217.6508 484.21064,221.18508 499.25086,221.18508 L537.57908,221.18508 L545.78163,201.67506 L563.96664,201.67506 L571.98828,221.18508 L645.84844,221.18508 L645.84844,202.65269 L657.0335,221.18508 L716.22061,221.18508 L716.22061,98.67789 L657.64543,98.67789 L657.64543,113.14614 L649.44288,98.67789 L589.33787,98.67789 L589.33787,113.14614 L581.80579,98.67789 L500.61839,98.67789 C487.02818,98.67789 475.08221,100.5669 465.43232,105.83121 L465.43232,98.67789 L409.40596,98.67789 L409.40596,105.83121 C403.26536,100.40529 394.89786,98.67789 385.59383,98.67789 L180.90796,98.67789 L167.17407,130.3194 L153.07037,98.67789 L88.59937,98.67789 L88.59937,113.14614 L81.516924,98.67789 L26.533518,98.67789 L0.999997,156.92445 L0.999997,221.18508 L1.002597,221.18508 L1.002688,221.18508 Z M228.39922,203.51436 L206.78472,203.51436 L206.70492,134.72064 L176.13228,203.51436 L157.62,203.51436 L126.96754,134.6597 L126.96754,203.51436 L84.084427,203.51436 L75.982981,183.92222 L32.083524,183.92222 L23.8996,203.51436 L1.000047,203.51436 L38.756241,115.67692 L70.08183,115.67692 L105.94103,198.84086 L105.94103,115.67692 L140.35289,115.67692 L167.94569,175.26406 L193.29297,115.67692 L228.39657,115.67692 L228.39657,203.51436 L228.39957,203.51436 L228.39922,203.51436 Z M68.777214,165.69287 L54.346265,130.67606 L39.997794,165.69287 L68.777214,165.69287 L68.777214,165.69287 Z M314.41947,203.51436 L243.98611,203.51436 L243.98611,115.67692 L314.41947,115.67692 L314.41947,133.96821 L265.07116,133.96821 L265.07116,149.8009 L313.23551,149.8009 L313.23551,167.80606 L265.07116,167.80606 L265.07116,185.34759 L314.41947,185.34759 L314.41947,203.51436 L314.41947,203.51436 Z M413.67528,139.33321 C413.67528,153.33782 404.28877,160.57326 398.81863,162.74575 C403.43206,164.49434 407.37237,167.58351 409.24808,170.14281 C412.22525,174.51164 412.73875,178.41416 412.73875,186.25897 L412.73875,203.51436 L391.47278,203.51436 L391.39298,192.43732 C391.39298,187.1518 391.90115,179.55074 388.0646,175.32499 C384.98366,172.23581 380.28774,171.56552 372.69714,171.56552 L350.06363,171.56552 L350.06363,203.51436 L328.98125,203.51436 L328.98125,115.67692 L377.47552,115.67692 C388.25084,115.67692 396.18999,115.9604 403.00639,119.88413 C409.67644,123.80786 413.67529,129.53581 413.67529,139.33321 L413.67528,139.33321 Z M387.02277,152.37632 C384.1254,154.12756 380.69859,154.18584 376.59333,154.18584 L350.97998,154.18584 L350.97998,134.67583 L376.94186,134.67583 C380.61611,134.67583 384.44999,134.8401 386.94029,136.26016 C389.67536,137.53981 391.36749,140.26337 391.36749,144.02548 C391.36749,147.86443 389.75784,150.95361 387.02277,152.37632 L387.02277,152.37632 Z M447.48908,203.51436 L425.97569,203.51436 L425.97569,115.67692 L447.48908,115.67692 L447.48908,203.51436 L447.48908,203.51436 Z M697.22856,203.51436 L667.35032,203.51436 L627.38585,137.58727 L627.38585,203.51436 L584.44687,203.51436 L576.24166,183.92222 L532.44331,183.92222 L524.48287,203.51436 L499.81137,203.51436 C489.56284,203.51436 476.58722,201.25709 469.23872,193.79909 C461.82903,186.3411 457.97386,176.23903 457.97386,160.26593 C457.97386,147.23895 460.27791,135.33 469.33983,125.91941 C476.15621,118.90916 486.83044,115.67692 501.35982,115.67692 L521.77174,115.67692 L521.77174,134.49809 L501.78818,134.49809 C494.0938,134.49809 489.74909,135.63733 485.564,139.70147 C481.96957,143.4 479.50322,150.39171 479.50322,159.59829 C479.50322,169.00887 481.38158,175.79393 485.30061,180.22633 C488.5465,183.70232 494.445,184.75677 499.99495,184.75677 L509.46393,184.75677 L539.17987,115.67957 L570.77152,115.67957 L606.46843,198.76138 L606.46843,115.67957 L638.5709,115.67957 L675.6327,176.85368 L675.6327,115.67957 L697.22856,115.67957 L697.22856,203.51436 L697.22856,203.51436 Z M569.07051,165.69287 L554.47993,130.67606 L539.96916,165.69287 L569.07051,165.69287 L569.07051,165.69287 Z" id="Path" fill="#FFFFFF" sketch:type="MSShapeGroup"></path>
11
+ <path d="M750.95644,343.76716 C745.83485,351.22516 735.85504,355.00582 722.34464,355.00582 L681.62723,355.00582 L681.62723,336.1661 L722.17969,336.1661 C726.20248,336.1661 729.01736,335.63887 730.71215,333.99096 C732.18079,332.63183 733.2051,330.65804 733.2051,328.26036 C733.2051,325.70107 732.18079,323.66899 730.62967,322.45028 C729.09984,321.10969 726.87294,320.50033 723.20135,320.50033 C703.40402,319.83005 678.70592,321.10969 678.70592,293.30714 C678.70592,280.56363 686.83131,267.14983 708.95664,267.14983 L750.95379,267.14983 L750.95379,249.66925 L711.93382,249.66925 C700.15812,249.66925 691.60438,252.47759 685.54626,256.84375 L685.54626,249.66925 L627.83044,249.66925 C618.60091,249.66925 607.76706,251.94771 602.64279,256.84375 L602.64279,249.66925 L499.57751,249.66925 L499.57751,256.84375 C491.37496,250.95154 477.53466,249.66925 471.14663,249.66925 L403.16366,249.66925 L403.16366,256.84375 C396.67452,250.58593 382.24357,249.66925 373.44772,249.66925 L297.3633,249.66925 L279.95252,268.43213 L263.64586,249.66925 L149.99149,249.66925 L149.99149,372.26121 L261.50676,372.26121 L279.447,353.20159 L296.34697,372.26121 L365.08554,372.32211 L365.08554,343.48364 L371.84339,343.48364 C380.96384,343.62405 391.72054,343.25845 401.21079,339.17311 L401.21079,372.25852 L457.90762,372.25852 L457.90762,340.30704 L460.64268,340.30704 C464.13336,340.30704 464.47657,340.45011 464.47657,343.92344 L464.47657,372.25587 L636.71144,372.25587 C647.64639,372.25587 659.07621,369.46873 665.40571,364.41107 L665.40571,372.25587 L720.03792,372.25587 C731.40656,372.25587 742.50913,370.66889 750.95644,366.60475 L750.95644,343.76712 L750.95644,343.76716 Z M409.45301,296.61266 C409.45301,321.01872 391.16689,326.05784 372.7371,326.05784 L346.42935,326.05784 L346.42935,355.52685 L305.44855,355.52685 L279.48667,326.44199 L252.5058,355.52685 L168.9904,355.52685 L168.9904,267.66822 L253.79086,267.66822 L279.73144,296.46694 L306.55002,267.66822 L373.92106,267.66822 C390.6534,267.66822 409.45301,272.28078 409.45301,296.61266 L409.45301,296.61266 Z M241.82781,337.04655 L189.9892,337.04655 L189.9892,319.56596 L236.27785,319.56596 L236.27785,301.64028 L189.9892,301.64028 L189.9892,285.66718 L242.84947,285.66718 L265.91132,311.27077 L241.82781,337.04655 L241.82781,337.04655 Z M325.3545,347.10668 L292.9833,311.3189 L325.3545,276.6677 L325.3545,347.10668 L325.3545,347.10668 Z M373.2272,308.04117 L345.98027,308.04117 L345.98027,285.66718 L373.47197,285.66718 C381.08388,285.66718 386.36777,288.75636 386.36777,296.43956 C386.36777,304.03796 381.32865,308.04117 373.2272,308.04117 L373.2272,308.04117 Z M515.97053,267.66822 L586.34004,267.66822 L586.34004,285.83764 L536.96778,285.83764 L536.96778,301.81074 L585.1348,301.81074 L585.1348,319.73642 L536.96778,319.73642 L536.96778,337.21701 L586.34004,337.29641 L586.34004,355.52678 L515.97053,355.52678 L515.97053,267.66815 L515.97053,267.66822 Z M488.91724,314.6973 C493.61049,316.42205 497.44703,319.51387 499.24559,322.07317 C502.22276,326.36251 502.65378,330.36571 502.73891,338.10985 L502.73891,355.52685 L481.5714,355.52685 L481.5714,344.53458 C481.5714,339.24908 482.08223,331.42282 478.1632,327.33748 C475.08226,324.19002 470.38635,323.4376 462.69463,323.4376 L440.16223,323.4376 L440.16223,355.52685 L418.97609,355.52685 L418.97609,267.66822 L467.65393,267.66822 C478.32816,267.66822 486.10236,268.13716 493.02251,271.81449 C499.6766,275.8177 503.86168,281.30191 503.86168,291.3245 C503.85868,305.34765 494.46719,312.50362 488.91724,314.6973 L488.91724,314.6973 Z M476.99899,303.59022 C474.17879,305.25668 470.69077,305.39975 466.58817,305.39975 L440.97483,305.39975 L440.97483,285.66718 L466.9367,285.66718 C470.69077,285.66718 474.4475,285.74658 476.99899,287.25416 C479.7314,288.67687 481.36499,291.39779 481.36499,295.15725 C481.36499,298.91672 479.7314,301.94496 476.99899,303.59022 L476.99899,303.59022 Z M667.33539,309.1866 C671.44067,313.41766 673.64095,318.7588 673.64095,327.80112 C673.64095,346.70178 661.78278,355.5242 640.51948,355.5242 L599.45353,355.5242 L599.45353,336.68449 L640.35453,336.68449 C644.35337,336.68449 647.18954,336.15726 648.9668,334.50934 C650.41681,333.15021 651.45709,331.17643 651.45709,328.77875 C651.45709,326.21944 650.33167,324.18738 648.88433,322.96866 C647.27201,321.62807 645.04778,321.01872 641.37619,321.01872 C621.65868,320.34843 596.9659,321.62807 596.9659,293.82551 C596.9659,281.08201 605.00615,267.66822 627.11019,267.66822 L669.37872,267.66822 L669.37872,286.36752 L630.70196,286.36752 C626.86809,286.36752 624.37512,286.51059 622.25464,287.9545 C619.94527,289.37721 619.08856,291.48876 619.08856,294.2759 C619.08856,297.59028 621.04941,299.8449 623.702,300.81987 C625.92624,301.59084 628.31543,301.81603 631.9072,301.81603 L643.25722,302.12071 C654.703,302.39889 662.55967,304.37003 667.33539,309.1866 L667.33539,309.1866 Z M751,285.66718 L712.57335,285.66718 C708.7368,285.66718 706.18797,285.81025 704.04088,287.25416 C701.81665,288.67687 700.95995,290.78843 700.95995,293.57558 C700.95995,296.88994 702.83831,299.14456 705.57071,300.11953 C707.79495,300.8905 710.18415,301.1157 713.6961,301.1157 L725.12327,301.42038 C736.65419,301.70387 744.35123,303.67765 749.04448,308.49157 C749.89852,309.16186 750.41202,309.91428 751,310.6667 L751,285.66718 L751,285.66718 Z" id="path13" fill="#FFFFFF" sketch:type="MSShapeGroup"></path>
12
+ </g>
13
+ </g>
14
+ </svg>
img/credit-cards/default.svg ADDED
@@ -0,0 +1,14 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+ <svg width="25px" height="18px" viewBox="0 0 25 18" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
3
+ <!-- Generator: Sketch 43.2 (39069) - http://www.bohemiancoding.com/sketch -->
4
+ <title>credit-card</title>
5
+ <desc>Created with Sketch.</desc>
6
+ <defs></defs>
7
+ <g id="wp-translation" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd" fill-opacity="0.57">
8
+ <g id="Bulk---Scroll-2" transform="translate(-1095.000000, -315.000000)" fill-rule="nonzero" fill="#000000">
9
+ <g id="credit-card" transform="translate(1095.000000, 315.000000)">
10
+ <path d="M22.5,4.5 L2.5,4.5 L2.5,2.25 L22.5,2.25 L22.5,4.5 Z M22.5,15.75 L2.5,15.75 L2.5,9 L22.5,9 L22.5,15.75 Z M22.5,0 L2.5,0 C1.1125,0 0,1.00125 0,2.25 L0,15.75 C0,16.9926407 1.11928813,18 2.5,18 L22.5,18 C23.8807119,18 25,16.9926407 25,15.75 L25,2.25 C25,1.00125 23.875,0 22.5,0 Z" id="Shape"></path>
11
+ </g>
12
+ </g>
13
+ </g>
14
+ </svg>
img/credit-cards/diners.svg ADDED
@@ -0,0 +1,15 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?xml version="1.0" encoding="UTF-8" standalone="no"?>
2
+ <svg width="750px" height="471px" viewBox="0 0 750 471" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:sketch="http://www.bohemiancoding.com/sketch/ns">
3
+ <!-- Generator: Sketch 3.3.2 (12043) - http://www.bohemiancoding.com/sketch -->
4
+ <title>diners</title>
5
+ <desc>Created with Sketch.</desc>
6
+ <defs></defs>
7
+ <g id="Page-1" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd" sketch:type="MSPage">
8
+ <g id="diners" sketch:type="MSLayerGroup">
9
+ <rect id="rectangle" fill="#0079BE" sketch:type="MSShapeGroup" x="0" y="0" width="750" height="471" rx="40"></rect>
10
+ <path d="M584.933911,237.947339 C584.933911,138.53154 501.952976,69.8140806 411.038924,69.8471464 L332.79674,69.8471464 C240.793699,69.8140806 165.066089,138.552041 165.066089,237.947339 C165.066089,328.877778 240.793699,403.587432 332.79674,403.150963 L411.038924,403.150963 C501.952976,403.586771 584.933911,328.857939 584.933911,237.947339 L584.933911,237.947339 Z" id="Shape-path" fill="#FFFFFF" sketch:type="MSShapeGroup"></path>
11
+ <path d="M333.280302,83.9308394 C249.210378,83.9572921 181.085889,152.238282 181.066089,236.510581 C181.085889,320.768331 249.209719,389.042708 333.280302,389.069161 C417.370025,389.042708 485.508375,320.768331 485.520254,236.510581 C485.507715,152.238282 417.370025,83.9572921 333.280302,83.9308394 L333.280302,83.9308394 Z" id="Shape-path" fill="#0079BE" sketch:type="MSShapeGroup"></path>
12
+ <path d="M237.066089,236.09774 C237.145288,194.917524 262.812421,159.801587 299.006443,145.847134 L299.006443,326.327183 C262.812421,312.380667 237.144628,277.283907 237.066089,236.09774 Z M368.066089,326.372814 L368.066089,145.847134 C404.273312,159.767859 429.980043,194.903637 430.046043,236.103692 C429.980043,277.316312 404.273312,312.425636 368.066089,326.372814 Z" id="Path" fill="#FFFFFF" sketch:type="MSShapeGroup"></path>
13
+ </g>
14
+ </g>
15
+ </svg>
img/credit-cards/discover.svg ADDED
@@ -0,0 +1,7 @@
 
 
 
 
 
 
 
1
+ <svg xmlns="http://www.w3.org/2000/svg" width="780" height="501" viewBox="0 0 780 501">
2
+ <g fill="none" fill-rule="evenodd">
3
+ <path fill="#4D4D4D" d="M54.992188,0 C24.626565,0 -4.7369516e-15,24.629374 0,55.003906 L0,445.99609 C0,476.37636 24.618673,501 54.992188,501 L725.00781,501 C755.37344,501 780,476.37062 780,445.99609 L780,268.55664 L780,55.003906 C780,24.623637 755.38133,-4.7369516e-15 725.00781,0 L54.992188,0 L54.992188,0 L54.992188,0 Z"/>
4
+ <path fill="#FFFFFF" d="M327.15234,161.89258 C335.9889,161.89258 343.40028,163.67723 352.41992,167.98242 L352.41992,190.73438 C343.87628,182.87089 336.46483,179.58008 326.66406,179.58008 C307.4002,179.58008 292.25,194.59455 292.25,213.63086 C292.25,233.70517 306.93133,247.82617 327.61914,247.82617 C336.93171,247.82617 344.20582,244.70584 352.41992,236.96875 L352.41992,259.73242 C343.07888,263.87291 335.50876,265.50781 326.66406,265.50781 C295.38621,265.50781 271.08203,242.91198 271.08203,213.77148 C271.08203,184.94507 296.03316,161.89258 327.15234,161.89258 L327.15234,161.89258 L327.15234,161.89258 Z M230.03906,162.51953 C241.58477,162.51953 252.14952,166.24004 260.98242,173.51367 L250.23438,186.76172 C244.88362,181.11594 239.82337,178.73438 233.66992,178.73438 C224.81668,178.73437 218.36914,183.47936 218.36914,189.72266 C218.36914,195.07734 221.98883,197.91138 234.31445,202.20508 C257.67927,210.24859 264.60352,217.3809 264.60352,233.13086 C264.60352,252.32421 249.62806,265.68359 228.2832,265.68359 C212.65323,265.68359 201.29008,259.88895 191.82617,246.8125 L205.09375,234.78125 C209.82489,243.39164 217.71615,248.00391 227.51367,248.00391 C236.67693,248.00391 243.46094,242.05155 243.46094,234.01953 C243.46094,229.85606 241.40612,226.28585 237.30273,223.76172 C235.2368,222.56668 231.1447,220.78491 223.10352,218.11523 C203.81198,211.57701 197.19336,204.58834 197.19336,190.92969 C197.19336,174.70478 211.40702,162.51953 230.03906,162.51953 L230.03906,162.51953 L230.03906,162.51953 Z M464.76172,164.24805 L487.19922,164.24805 L515.2832,230.83984 L543.72852,164.24805 L565.99609,164.24805 L520.50195,265.93359 L509.44922,265.93359 L464.76172,164.24805 L464.76172,164.24805 L464.76172,164.24805 Z M67.414062,164.40039 L97.564453,164.40039 C130.87609,164.40039 154.09766,184.78179 154.09766,214.04102 C154.09766,228.63041 146.99364,242.73654 134.98047,252.09766 C124.87172,259.99945 113.35396,263.54297 97.40625,263.54297 L67.414062,263.54297 L67.414062,164.40039 L67.414062,164.40039 L67.414062,164.40039 Z M163.54883,164.40039 L184.08984,164.40039 L184.08984,263.54297 L163.54883,263.54297 L163.54883,164.40039 L163.54883,164.40039 L163.54883,164.40039 Z M575.2832,164.40039 L633.53516,164.40039 L633.53516,181.19922 L595.80859,181.19922 L595.80859,203.20508 L632.14453,203.20508 L632.14453,219.99609 L595.80859,219.99609 L595.80859,246.75781 L633.53516,246.75781 L633.53516,263.54297 L575.2832,263.54297 L575.2832,164.40039 L575.2832,164.40039 L575.2832,164.40039 Z M647.14062,164.40039 L677.5957,164.40039 C701.28599,164.40039 714.86133,175.11052 714.86133,193.67188 C714.86133,208.85113 706.34712,218.81273 690.875,221.77734 L724.02344,263.54297 L698.76367,263.54297 L670.33398,223.71484 L667.65625,223.71484 L667.65625,263.54297 L647.14062,263.54297 L647.14062,164.40039 L647.14062,164.40039 L647.14062,164.40039 Z M667.65625,180.01562 L667.65625,210.04102 L673.6582,210.04102 C686.77472,210.04102 693.72656,204.67918 693.72656,194.71289 C693.72656,185.06451 686.77347,180.01562 673.98242,180.01562 L667.65625,180.01562 L667.65625,180.01562 L667.65625,180.01562 Z M87.939453,181.19922 L87.939453,246.75781 L93.451172,246.75781 C106.72432,246.75781 115.10685,244.36382 121.56055,238.87891 C128.66438,232.92288 132.9375,223.41276 132.9375,213.89844 C132.9375,204.39943 128.66438,195.17283 121.56055,189.2168 C114.77608,183.43696 106.72432,181.19922 93.451172,181.19922 L87.939453,181.19922 L87.939453,181.19922 L87.939453,181.19922 Z"/>
5
+ <path fill="#F47216" d="M415.13086 161.21289C446.07103 161.21289 471.15234 184.79287 471.15234 213.92188L471.15234 213.95508C471.15234 243.08408 446.07103 266.69727 415.13086 266.69727 384.19069 266.69727 359.10938 243.08408 359.10938 213.95508L359.10938 213.92188C359.10938 184.79287 384.19069 161.21289 415.13086 161.21289L415.13086 161.21289 415.13086 161.21289zM779.981917 288.361069C753.932037 306.691919 558.904907 437.700579 221.228007 500.98412L724.989727 500.98412C755.355357 500.98412 779.981917 476.35474 779.981917 445.980209L779.981917 288.361069 779.981917 288.361069 779.981917 288.361069z"/>
6
+ </g>
7
+ </svg>
img/credit-cards/hipercard.svg ADDED
@@ -0,0 +1,7 @@
 
 
 
 
 
 
 
1
+ <?xml version="1.0" encoding="utf-8"?>
2
+ <svg id="Layer_1" x="0px" y="0px" width="780px" height="501px" viewBox="0 0 780 501" xmlns="http://www.w3.org/2000/svg">
3
+ <title>amex-outline</title>
4
+ <desc>Created with Sketch.</desc>
5
+ <path d="M725,0H55C24.673,0,0,24.673,0,55v391c0,30.327,24.673,55,55,55h670c30.325,0,55-24.673,55-55V55&#10;&#9;C780,24.673,755.325,0,725,0z" style="fill: rgb(255, 255, 255);"/>
6
+ <path id="path2997" d="M 339.927 390.424 L 53.393 390.527 L 53.393 389.837 C 53.393 389.458 53.85 386.999 54.408 384.372 C 54.967 381.746 55.835 377.568 56.339 375.089 C 56.841 372.609 57.701 368.396 58.248 365.725 C 58.796 363.056 59.707 358.608 60.272 355.842 C 60.836 353.077 61.72 348.707 62.237 346.133 C 62.754 343.557 63.615 339.343 64.153 336.769 C 64.69 334.194 65.607 329.747 66.19 326.886 C 66.772 324.025 67.657 319.655 68.157 317.175 C 68.657 314.695 69.451 310.872 69.922 308.68 C 70.392 306.486 70.993 303.521 71.255 302.09 C 71.518 300.66 72.369 296.446 73.146 292.727 C 73.923 289.008 74.779 284.794 75.051 283.364 C 75.322 281.933 76.183 277.719 76.965 274 C 77.746 270.282 78.604 266.068 78.872 264.637 C 79.14 263.207 80.003 258.993 80.789 255.274 C 81.577 251.554 82.427 247.419 82.677 246.084 C 82.929 244.749 83.617 241.316 84.207 238.455 C 84.796 235.594 85.912 230.21 86.686 226.491 C 87.461 222.771 88.785 216.295 89.628 212.098 C 90.473 207.902 91.482 202.909 91.871 201.002 C 92.259 199.095 92.962 195.661 93.433 193.372 C 93.904 191.083 94.758 186.948 95.332 184.183 C 95.906 181.416 96.839 176.891 97.406 174.125 C 97.974 171.36 98.848 167.068 99.349 164.589 C 99.85 162.109 100.705 157.974 101.249 155.399 C 101.793 152.824 102.729 148.298 103.329 145.342 C 103.929 142.385 104.934 137.86 105.562 135.285 C 106.19 132.71 107.078 129.589 107.536 128.35 C 107.993 127.109 109.256 124.423 110.342 122.377 L 112.317 118.66 L 114.112 116.308 C 115.098 115.016 116.861 112.973 118.028 111.769 C 119.195 110.565 121.163 108.753 122.404 107.743 C 123.643 106.732 125.438 105.368 126.391 104.712 C 127.345 104.056 129.218 102.907 130.553 102.159 C 131.888 101.411 133.762 100.432 134.715 99.983 C 135.669 99.534 137.62 98.713 139.05 98.16 C 140.48 97.608 143.211 96.681 145.118 96.102 C 147.025 95.522 150.606 94.648 153.075 94.161 C 155.544 93.673 159.444 93.021 161.745 92.712 L 165.926 92.15 L 452.633 92.042 L 739.339 91.931 L 739.339 92.621 C 739.339 93 738.879 95.459 738.318 98.085 C 737.755 100.711 736.816 105.201 736.23 108.062 C 735.643 110.923 734.789 115.059 734.329 117.252 C 733.87 119.446 733 123.659 732.396 126.615 C 731.793 129.572 730.864 134.098 730.333 136.672 C 729.802 139.247 728.941 143.461 728.421 146.035 C 727.901 148.611 727.035 152.824 726.498 155.399 C 725.959 157.974 725.127 162.032 724.645 164.416 C 724.163 166.8 723.292 171.091 722.709 173.952 C 722.125 176.813 721.188 181.339 720.626 184.009 C 720.063 186.679 719.208 190.815 718.724 193.199 C 718.238 195.583 717.367 199.874 716.786 202.735 C 716.204 205.596 715.269 210.122 714.707 212.793 C 714.145 215.463 713.308 219.52 712.846 221.809 C 712.385 224.097 711.516 228.389 710.916 231.345 C 710.315 234.301 709.442 238.593 708.972 240.883 C 708.502 243.171 707.665 247.229 707.111 249.898 C 706.555 252.569 705.606 257.173 705.003 260.129 C 704.397 263.086 703.532 267.298 703.08 269.493 C 702.626 271.685 701.779 275.821 701.195 278.681 C 700.612 281.544 699.684 286.068 699.132 288.739 C 698.581 291.409 697.717 295.623 697.211 298.103 C 696.707 300.582 695.828 304.874 695.261 307.639 C 694.692 310.404 693.764 314.93 693.198 317.695 C 692.632 320.461 691.784 324.597 691.313 326.886 C 690.842 329.174 689.982 333.388 689.401 336.249 C 688.82 339.11 687.874 343.619 687.3 346.268 L 686.256 351.085 L 685.012 354.417 C 684.328 356.25 683.299 358.686 682.725 359.831 C 682.153 360.974 680.986 362.994 680.133 364.318 C 679.279 365.641 678.089 367.336 677.489 368.085 C 676.889 368.834 675.082 370.768 673.472 372.384 L 670.549 375.319 L 667.734 377.319 C 666.186 378.419 664.518 379.538 664.029 379.805 C 663.539 380.072 661.674 381.025 659.884 381.92 C 658.095 382.817 655.566 383.957 654.267 384.454 C 652.967 384.953 650.392 385.8 648.545 386.337 C 646.698 386.876 644.718 387.406 644.146 387.515 C 643.573 387.625 641.588 388.035 639.732 388.429 C 637.877 388.822 634.132 389.409 631.41 389.733 L 626.46 390.322 L 339.927 390.424 Z M 237.983 316.309 L 245.439 316.309 L 245.649 315.76 C 245.766 315.458 245.86 314.749 245.86 314.184 C 245.86 313.618 246.106 311.564 246.407 309.618 C 246.707 307.67 247.411 303.191 247.973 299.663 C 248.534 296.134 249.374 290.828 249.84 287.872 C 250.306 284.915 250.875 281.131 251.105 279.462 C 251.334 277.793 251.613 276.428 251.726 276.428 C 251.838 276.428 252.32 277.165 252.797 278.067 L 253.663 279.705 L 255.585 281.643 L 257.508 283.579 L 259.874 284.527 L 262.241 285.474 L 265.061 285.84 L 267.882 286.205 L 271.461 285.986 L 275.041 285.766 L 278.917 284.763 L 282.794 283.759 L 284.874 282.811 C 286.019 282.288 288.047 281.149 289.382 280.279 L 291.81 278.698 L 294.073 276.435 C 295.318 275.193 297.074 273.197 297.974 272.002 C 298.876 270.808 299.613 269.744 299.613 269.638 C 299.613 269.531 300.056 268.792 300.597 267.994 C 301.138 267.197 302.244 264.983 303.056 263.076 C 303.869 261.169 305.137 257.736 305.877 255.447 L 307.221 251.285 L 307.916 247.681 C 308.298 245.699 308.79 242.422 309.009 240.398 L 309.406 236.721 L 309.176 233.6 L 308.947 230.479 L 308.223 227.357 L 307.5 224.236 L 306.328 221.9 L 305.157 219.563 L 302.894 217.164 L 300.632 214.765 L 297.955 213.382 L 295.278 211.999 L 292.33 211.292 L 289.382 210.587 L 286.434 210.371 L 283.487 210.155 L 280.204 210.532 L 276.919 210.909 L 274.24 211.594 L 271.56 212.277 L 269.231 213.356 C 267.951 213.947 266.087 214.954 265.091 215.592 C 264.094 216.23 263.065 216.963 262.805 217.222 C 262.546 217.481 261.923 217.962 261.423 218.288 L 260.512 218.885 L 261.148 215.838 C 261.499 214.163 261.791 212.598 261.799 212.358 L 261.813 211.925 L 255.454 211.925 L 249.097 211.925 L 247.983 218.948 C 247.369 222.811 246.401 228.779 245.831 232.213 C 245.261 235.646 244.4 240.795 243.92 243.656 C 243.44 246.517 242.583 251.589 242.015 254.927 C 241.448 258.264 240.511 263.571 239.932 266.718 C 239.353 269.865 238.506 274.469 238.048 276.949 C 237.591 279.428 236.729 284.109 236.135 287.351 C 235.541 290.595 234.585 295.744 234.011 298.796 C 233.437 301.847 232.504 306.685 231.937 309.546 C 231.369 312.407 230.821 315.1 230.716 315.528 L 230.527 316.309 L 237.983 316.309 Z M 270.083 276.214 L 267.188 276.388 L 265.296 276.053 L 263.403 275.719 L 261.481 274.842 L 259.558 273.964 L 258.216 272.681 L 256.873 271.4 L 256.098 269.666 C 255.671 268.712 255.124 267.092 254.881 266.065 L 254.439 264.199 L 254.616 261.21 L 254.794 258.222 L 255.687 253.54 C 256.178 250.965 257.06 246.127 257.647 242.79 C 258.234 239.452 259.124 234.56 259.623 231.921 L 260.53 227.121 L 262.518 225.467 C 263.612 224.558 265.344 223.338 266.368 222.758 L 268.228 221.702 L 270.655 220.951 L 273.083 220.199 L 276.204 220.016 L 279.325 219.833 L 281.867 220.375 L 284.408 220.916 L 286.202 221.742 L 287.995 222.568 L 289.499 224.08 L 291.004 225.592 L 291.814 227.193 C 292.261 228.074 292.888 229.797 293.207 231.023 L 293.788 233.252 L 293.61 239.842 L 293.432 246.431 L 292.542 250.326 C 292.052 252.468 291.12 255.745 290.47 257.608 L 289.289 260.996 L 287.841 263.738 C 287.045 265.247 285.818 267.285 285.114 268.268 C 284.41 269.25 283.287 270.525 282.619 271.097 C 281.953 271.671 280.834 272.568 280.135 273.089 L 278.864 274.038 L 275.921 275.039 L 272.978 276.04 L 270.083 276.214 Z M 342.094 285.747 L 345.909 285.791 L 349.723 285.443 C 351.822 285.252 355.255 284.853 357.352 284.557 C 359.451 284.262 363.075 283.6 365.407 283.088 L 369.646 282.155 L 369.858 280.591 C 369.974 279.732 370.45 277.174 370.916 274.906 L 371.763 270.781 L 371.575 270.595 L 371.389 270.409 L 370.093 271.034 C 369.38 271.378 367.159 272.2 365.159 272.859 L 361.521 274.057 L 357.703 274.798 L 353.885 275.537 L 347.816 275.55 L 341.747 275.56 L 339.666 274.896 C 338.522 274.531 336.839 273.863 335.926 273.41 L 334.267 272.589 L 332.897 271.351 L 331.527 270.113 L 330.458 268.246 L 329.389 266.377 L 328.719 264.035 L 328.049 261.692 L 328.045 257.356 L 328.04 253.019 L 328.634 249.152 L 329.23 245.283 L 334.448 245.039 L 339.666 244.795 L 358.957 244.92 L 378.247 245.043 L 378.829 242.573 C 379.15 241.214 379.64 238.405 379.918 236.331 L 380.424 232.559 L 380.435 229.387 L 380.446 226.214 L 379.897 223.845 L 379.347 221.477 L 378.438 219.909 C 377.94 219.047 377.059 217.797 376.483 217.131 C 375.907 216.466 374.878 215.528 374.197 215.047 C 373.515 214.566 372.178 213.757 371.224 213.25 L 369.49 212.328 L 366.461 211.598 L 363.431 210.869 L 359.699 210.512 L 355.965 210.155 L 352.498 210.381 L 349.03 210.606 L 344.868 211.405 L 340.707 212.205 L 338.105 213.244 C 336.675 213.815 334.49 214.859 333.251 215.562 C 332.011 216.265 330.295 217.409 329.437 218.104 C 328.577 218.8 327.091 220.152 326.134 221.109 C 325.176 222.067 323.758 223.785 322.985 224.93 C 322.211 226.075 321.025 228.103 320.348 229.438 C 319.672 230.774 318.791 232.646 318.39 233.6 C 317.99 234.553 317.261 236.504 316.772 237.934 C 316.282 239.365 315.513 242.096 315.063 244.004 C 314.612 245.911 313.995 249.05 313.69 250.98 L 313.137 254.49 L 313.143 259.65 L 313.148 264.81 L 313.675 267.065 C 313.964 268.304 314.519 270.178 314.906 271.226 C 315.293 272.275 316.011 273.836 316.499 274.694 C 316.987 275.552 318.031 276.934 318.817 277.765 C 319.603 278.596 321.027 279.857 321.981 280.566 C 322.934 281.276 324.632 282.275 325.753 282.785 L 327.792 283.713 L 330.635 284.401 C 332.198 284.778 334.558 285.226 335.879 285.396 C 337.199 285.565 339.996 285.724 342.094 285.747 Z M 348.625 236.894 C 339.025 236.894 331.17 236.826 331.17 236.741 C 331.17 236.658 331.58 235.448 332.081 234.053 C 332.581 232.659 333.461 230.585 334.034 229.443 L 335.079 227.366 L 337.372 225.085 L 339.666 222.802 L 341.921 221.725 C 343.16 221.132 344.799 220.486 345.561 220.29 C 346.325 220.094 348.509 219.834 350.416 219.713 L 353.885 219.49 L 356.549 219.833 L 359.211 220.175 L 361.146 221.061 L 363.082 221.947 L 364.144 223.092 C 364.727 223.721 365.423 224.648 365.69 225.151 L 366.174 226.067 L 366.494 228.099 L 366.815 230.131 L 366.448 233.512 L 366.082 236.894 L 348.625 236.894 Z M 452.375 285.749 L 456.192 285.791 L 460.524 285.278 C 462.907 284.995 466.079 284.528 467.574 284.237 C 469.067 283.948 471.486 283.373 472.949 282.961 C 474.411 282.547 475.734 282.1 475.889 281.968 C 476.044 281.835 476.456 280.261 476.807 278.47 C 477.157 276.68 477.599 274.278 477.788 273.134 C 477.976 271.989 478.074 270.992 478.005 270.917 C 477.935 270.842 477.68 270.939 477.437 271.131 C 477.193 271.325 475.492 272.041 473.655 272.723 L 470.316 273.963 L 465.561 274.884 L 460.805 275.805 L 456.763 275.668 L 452.72 275.53 L 450.423 274.733 L 448.126 273.936 L 446.352 272.385 L 444.578 270.832 L 443.4 268.688 L 442.224 266.545 L 441.662 263.676 L 441.102 260.808 L 441.106 257.088 L 441.109 253.367 L 441.79 248.859 L 442.472 244.35 L 443.192 241.922 C 443.589 240.587 444.038 239.027 444.189 238.455 C 444.342 237.882 444.977 236.244 445.603 234.813 C 446.228 233.383 447.344 231.172 448.082 229.9 L 449.424 227.589 L 451.073 225.88 L 452.722 224.171 L 454.467 223.089 L 456.214 222.006 L 458.456 221.315 C 459.689 220.935 461.869 220.442 463.299 220.22 L 465.9 219.814 L 469.714 220.006 L 473.529 220.197 L 478.037 221.1 L 482.546 222.001 L 484.379 222.685 C 485.387 223.061 486.256 223.37 486.311 223.37 C 486.364 223.37 486.606 222.082 486.848 220.508 C 487.09 218.935 487.52 216.346 487.804 214.756 C 488.089 213.164 488.253 211.794 488.168 211.711 C 488.085 211.627 486.73 211.412 485.158 211.233 C 483.585 211.054 479.311 210.736 475.66 210.525 L 469.021 210.144 L 464.339 210.503 L 459.658 210.863 L 456.189 211.591 L 452.722 212.32 L 450.488 213.213 C 449.26 213.704 447.461 214.591 446.49 215.183 C 445.519 215.776 444.285 216.572 443.745 216.953 C 443.205 217.335 441.569 218.823 440.107 220.261 L 437.452 222.875 L 435.968 225.047 C 435.153 226.242 433.743 228.732 432.834 230.583 L 431.182 233.947 L 429.915 237.587 C 429.219 239.59 428.246 242.867 427.755 244.87 L 426.86 248.512 L 426.535 251.806 L 426.211 255.101 L 426.214 259.436 L 426.218 263.77 L 426.545 266.292 L 426.872 268.814 L 427.911 271.408 L 428.949 274.002 L 430.15 275.877 L 431.349 277.752 L 433.256 279.63 L 435.165 281.507 L 437.182 282.575 L 439.201 283.641 L 441.852 284.378 C 443.309 284.782 445.416 285.247 446.533 285.41 C 447.65 285.573 450.281 285.726 452.381 285.749 Z M 509.419 285.621 L 514.1 285.486 L 517.048 284.732 L 519.996 283.977 L 521.904 283.076 C 522.953 282.581 524.669 281.602 525.718 280.901 C 526.767 280.2 528.392 278.868 529.327 277.941 C 530.262 277.013 531.649 275.431 532.409 274.425 C 533.169 273.418 533.837 272.64 533.893 272.697 C 533.95 272.753 533.774 274.356 533.504 276.26 C 533.235 278.165 533.011 280.698 533.007 281.89 L 533.001 284.057 L 539.365 284.057 L 545.73 284.057 L 545.925 279.116 L 546.119 274.174 L 547.027 267.758 C 547.527 264.229 548.334 259.001 548.821 256.141 C 549.307 253.28 550.152 248.443 550.7 245.39 C 551.247 242.338 552.114 237.579 552.625 234.813 L 553.557 229.785 L 553.589 225.442 L 553.619 221.098 L 552.638 219.091 L 551.655 217.083 L 550.324 215.805 L 548.991 214.526 L 546.806 213.419 L 544.619 212.31 L 541.36 211.585 L 538.101 210.86 L 533.615 210.519 L 529.128 210.178 L 523.349 210.536 C 520.169 210.732 515.697 211.12 513.408 211.399 L 509.246 211.903 L 506.41 211.914 L 503.574 211.925 L 503.161 213.92 C 502.934 215.016 502.303 217.621 501.76 219.71 C 501.215 221.798 500.821 223.556 500.883 223.618 C 500.944 223.68 502.461 223.335 504.253 222.853 C 506.045 222.37 509.853 221.578 512.715 221.09 L 517.916 220.204 L 522.597 220.012 L 527.279 219.818 L 530.295 220.347 L 533.311 220.876 L 535.323 221.869 L 537.336 222.863 L 538.463 224.543 L 539.591 226.222 L 539.575 228.87 L 539.558 231.519 L 538.961 234.425 L 538.363 237.332 L 525.885 237.377 L 513.407 237.421 L 509.324 238.541 C 507.078 239.157 504.591 239.975 503.797 240.358 C 503.003 240.742 502.209 241.056 502.032 241.056 C 501.856 241.056 500.52 241.796 499.063 242.703 L 496.415 244.348 L 494.33 246.43 C 493.182 247.575 491.717 249.292 491.073 250.246 C 490.429 251.199 489.382 253.191 488.748 254.673 L 487.594 257.366 L 487.064 260.394 L 486.534 263.423 L 486.534 266.6 L 486.534 269.778 L 487.039 272.424 L 487.546 275.069 L 488.484 276.794 C 489.001 277.742 489.95 279.133 490.591 279.883 L 491.759 281.247 L 493.832 282.507 L 495.906 283.767 L 498.281 284.438 C 499.587 284.807 501.574 285.255 502.698 285.433 L 504.74 285.755 L 509.422 285.621 Z M 513.754 275.923 L 510.979 276.069 L 509.142 275.6 C 508.132 275.343 506.598 274.769 505.734 274.325 L 504.165 273.518 L 503.307 272.499 C 502.836 271.938 502.116 270.838 501.707 270.053 L 500.964 268.625 L 500.819 265.292 L 500.672 261.958 L 501.26 259.936 C 501.583 258.824 502.342 256.893 502.946 255.647 L 504.044 253.38 L 506.147 251.293 L 508.249 249.205 L 510.481 248.13 L 512.713 247.056 L 515.487 246.396 L 518.262 245.737 L 526.932 245.737 L 535.602 245.737 L 536.15 245.964 L 536.698 246.19 L 536.237 248.912 C 535.983 250.408 535.378 253.115 534.891 254.927 C 534.405 256.74 533.547 259.403 532.984 260.846 C 532.421 262.29 531.96 263.566 531.96 263.682 C 531.96 263.799 531.39 264.85 530.693 266.019 L 529.427 268.146 L 527.348 270.207 C 526.205 271.339 525.142 272.266 524.988 272.266 C 524.835 272.266 524.134 272.657 523.431 273.134 L 522.153 274 L 519.34 274.89 L 516.528 275.779 L 513.754 275.923 Z M 626.633 285.744 L 629.927 285.786 L 633.049 285.279 C 634.766 285.001 636.95 284.552 637.904 284.282 C 638.857 284.012 640.575 283.312 641.718 282.726 L 643.8 281.66 L 645.59 280.084 L 647.379 278.508 L 649.265 275.995 C 650.302 274.612 651.24 273.247 651.351 272.96 L 651.552 272.439 L 651.377 274.174 C 651.281 275.127 651.066 276.688 650.897 277.642 C 650.729 278.596 650.49 280.429 650.364 281.717 L 650.134 284.057 L 656.938 284.057 L 663.74 284.057 L 663.74 281.717 L 663.74 279.376 L 664.776 270.532 C 665.346 265.668 666.189 259.193 666.649 256.141 C 667.109 253.088 667.82 248.72 668.229 246.431 C 668.636 244.142 669.359 240.006 669.833 237.241 C 670.309 234.476 671.167 229.637 671.741 226.491 C 672.314 223.343 673.233 218.35 673.782 215.394 C 674.33 212.437 675.184 207.833 675.677 205.163 C 676.17 202.493 677.054 197.811 677.641 194.76 C 678.23 191.708 679.086 187.416 679.547 185.222 C 680.009 183.03 680.386 181.117 680.385 180.975 L 680.385 180.714 L 672.963 180.714 L 665.541 180.714 L 665.322 182.882 C 665.202 184.074 664.633 188.014 664.06 191.639 C 663.486 195.262 662.55 201.036 661.98 204.469 C 661.41 207.902 660.862 211.232 660.761 211.868 L 660.575 213.024 L 659.99 212.775 C 659.668 212.638 657.921 212.153 656.11 211.698 L 652.816 210.871 L 648.308 210.52 L 643.799 210.169 L 639.984 210.524 L 636.17 210.88 L 632.702 211.757 L 629.234 212.633 L 625.94 214.24 L 622.644 215.847 L 620.217 217.643 L 617.79 219.44 L 615.693 221.689 C 614.54 222.925 612.875 224.97 611.991 226.233 L 610.387 228.529 L 608.501 232.451 C 607.465 234.609 606.203 237.466 605.698 238.801 C 605.192 240.137 604.302 243.096 603.717 245.378 L 602.656 249.528 L 602.133 254.916 L 601.61 260.302 L 602.002 264.637 L 602.396 268.972 L 602.859 270.532 C 603.116 271.391 603.653 272.92 604.056 273.93 L 604.788 275.769 L 606.123 277.575 L 607.459 279.383 L 608.983 280.631 L 610.507 281.88 L 612.588 282.914 C 613.733 283.481 615.652 284.216 616.854 284.545 C 618.055 284.874 620.006 285.27 621.189 285.423 C 622.371 285.577 624.82 285.722 626.633 285.744 Z M 632.546 275.907 L 629.927 276.044 L 628.161 275.726 C 627.189 275.552 625.634 275.082 624.704 274.684 L 623.015 273.961 L 621.593 272.795 L 620.172 271.631 L 619.116 269.608 L 618.06 267.585 L 617.577 265.331 L 617.097 263.076 L 617.138 258.568 L 617.178 254.06 L 617.737 250.071 L 618.296 246.084 L 619.165 243.31 C 619.643 241.784 620.037 240.344 620.039 240.11 C 620.043 239.877 620.513 238.629 621.088 237.337 C 621.662 236.044 622.62 234.051 623.218 232.906 C 623.816 231.761 624.934 229.978 625.701 228.942 C 626.47 227.906 627.839 226.345 628.743 225.473 C 629.647 224.603 631.084 223.459 631.939 222.934 L 633.491 221.979 L 636.218 221.035 L 638.944 220.091 L 644.666 220.088 L 650.388 220.088 L 653.682 221.003 C 655.495 221.505 657.419 222.088 657.958 222.298 L 658.939 222.679 L 658.748 223.631 C 658.643 224.155 658.23 226.456 657.832 228.744 C 657.434 231.033 656.648 235.403 656.087 238.455 C 655.526 241.507 654.664 246.111 654.171 248.685 C 653.679 251.26 652.966 254.537 652.586 255.967 C 652.207 257.398 651.671 259.379 651.396 260.37 C 651.121 261.361 650.467 263.079 649.942 264.185 C 649.417 265.292 648.498 266.9 647.9 267.758 C 647.302 268.616 646.292 269.806 645.654 270.4 C 645.015 270.996 643.635 272.052 642.586 272.749 L 640.679 274.017 L 637.922 274.892 L 635.165 275.767 L 632.546 275.907 Z M 122.161 284.057 L 130.586 284.057 L 131.191 280.33 C 131.523 278.279 132.173 274.338 132.634 271.573 C 133.095 268.808 133.954 263.657 134.541 260.129 C 135.129 256.6 136.011 251.372 136.5 248.512 C 136.989 245.651 137.767 241.213 138.227 238.65 C 138.688 236.085 139.153 233.901 139.259 233.794 L 139.454 233.6 L 162.111 233.6 L 184.767 233.6 L 185.019 233.851 L 185.271 234.103 L 184.877 236.105 C 184.662 237.207 184.023 240.604 183.458 243.656 C 182.893 246.708 181.943 251.858 181.346 255.101 C 180.751 258.343 179.889 262.947 179.432 265.331 C 178.974 267.715 178.048 272.708 177.374 276.428 C 176.701 280.147 176.151 283.385 176.153 283.624 L 176.157 284.057 L 184.617 284.057 L 193.078 284.057 L 193.452 281.89 C 193.659 280.698 193.989 278.552 194.189 277.122 C 194.387 275.691 194.868 272.647 195.255 270.359 C 195.642 268.071 196.415 263.544 196.974 260.302 C 197.532 257.06 198.468 251.52 199.052 247.991 C 199.636 244.462 200.502 239.313 200.978 236.548 C 201.452 233.781 202.299 229.1 202.858 226.144 C 203.417 223.187 204.349 218.194 204.929 215.046 C 205.509 211.9 206.376 207.14 206.858 204.469 C 207.34 201.799 208.218 196.961 208.81 193.719 C 209.402 190.477 210.149 186.693 210.47 185.309 L 211.054 182.795 L 202.488 182.795 L 193.921 182.795 L 193.688 184.443 C 193.561 185.348 193.147 187.885 192.769 190.078 C 192.39 192.272 191.704 196.172 191.242 198.747 C 190.78 201.323 189.936 206.238 189.366 209.672 C 188.796 213.104 188.07 217.649 187.752 219.771 L 187.174 223.628 L 174.599 223.883 L 162.023 224.137 L 151.491 223.887 C 145.698 223.75 140.926 223.609 140.886 223.577 C 140.847 223.543 141.044 222.196 141.324 220.582 C 141.605 218.968 142.135 216.164 142.503 214.353 C 142.871 212.541 143.569 208.952 144.053 206.376 C 144.538 203.802 145.086 200.603 145.273 199.268 C 145.459 197.933 145.85 195.709 146.141 194.325 C 146.432 192.943 146.984 190.03 147.368 187.853 C 147.751 185.676 148.16 183.647 148.277 183.345 L 148.487 182.795 L 139.99 182.795 L 131.492 182.795 L 130.949 185.83 C 130.649 187.499 130.25 189.878 130.062 191.118 C 129.873 192.358 129.24 196.337 128.655 199.961 C 128.07 203.585 127.206 208.969 126.735 211.925 C 126.264 214.882 125.408 220.266 124.832 223.889 C 124.254 227.514 123.303 233.131 122.716 236.373 C 122.13 239.617 121.281 244.22 120.829 246.604 C 120.378 248.988 119.519 253.514 118.919 256.661 C 118.32 259.809 117.443 264.256 116.974 266.545 C 116.504 268.833 115.985 271.486 115.821 272.439 C 115.655 273.393 115.119 276.144 114.627 278.552 C 114.136 280.96 113.734 283.183 113.734 283.494 L 113.734 284.057 L 122.161 284.057 Z M 215.439 284.057 L 222.898 284.057 L 223.108 283.509 C 223.225 283.206 223.319 282.415 223.319 281.751 C 223.319 281.085 223.789 277.625 224.361 274.062 C 224.935 270.499 225.882 264.698 226.467 261.169 C 227.051 257.641 227.914 252.491 228.385 249.725 C 228.856 246.96 229.692 242.357 230.244 239.494 C 230.796 236.634 231.644 232.186 232.128 229.612 C 232.611 227.037 233.563 222.138 234.242 218.725 C 234.921 215.312 235.561 212.384 235.664 212.217 L 235.853 211.912 L 228.31 212.005 L 220.767 212.098 L 220.137 216.607 C 219.793 219.087 219.037 224.003 218.459 227.53 C 217.882 231.059 217.008 236.444 216.517 239.494 C 216.026 242.547 215.172 247.462 214.617 250.419 C 214.062 253.375 213.212 257.9 212.727 260.475 C 212.243 263.051 211.374 267.576 210.796 270.532 C 210.218 273.489 209.443 277.39 209.073 279.202 C 208.702 281.015 208.305 282.848 208.189 283.277 L 207.98 284.057 L 215.439 284.057 Z M 389.899 284.057 L 397.303 284.057 L 397.525 280.924 C 397.648 279.202 398.066 275.729 398.456 273.208 C 398.846 270.687 399.645 265.66 400.23 262.037 C 400.816 258.412 401.904 252.38 402.648 248.631 C 403.394 244.883 404.235 241.157 404.519 240.352 C 404.804 239.546 405.036 238.674 405.036 238.413 C 405.036 238.151 405.593 236.727 406.273 235.248 C 406.953 233.769 408.221 231.505 409.091 230.216 L 410.672 227.872 L 412.787 225.912 L 414.903 223.954 L 417.512 222.708 L 420.121 221.461 L 424.11 221.483 L 428.097 221.504 L 430.058 222.089 C 431.136 222.411 432.111 222.675 432.225 222.675 C 432.339 222.675 432.432 222.307 432.432 221.856 C 432.432 221.406 432.822 219.122 433.299 216.78 C 433.775 214.439 434.166 212.425 434.166 212.304 C 434.166 212.183 433.035 211.74 431.652 211.32 C 430.269 210.9 428.357 210.46 427.404 210.341 L 425.67 210.127 L 423.416 210.526 C 422.176 210.745 420.333 211.229 419.32 211.602 C 418.306 211.974 416.633 212.818 415.601 213.478 C 414.57 214.139 412.965 215.425 412.036 216.336 C 411.105 217.248 409.541 219.087 408.56 220.422 C 407.578 221.757 406.552 223.162 406.279 223.543 L 405.783 224.236 L 406.084 222.85 C 406.25 222.086 406.712 219.589 407.11 217.301 C 407.508 215.012 407.919 212.865 408.019 212.533 L 408.204 211.925 L 401.592 211.925 L 394.979 211.925 L 394.979 212.761 C 394.979 213.221 394.588 215.99 394.112 218.916 C 393.635 221.843 392.848 226.733 392.364 229.785 C 391.88 232.837 391.02 238.143 390.454 241.576 C 389.888 245.009 389.028 249.925 388.543 252.499 C 388.058 255.074 387.198 259.6 386.63 262.557 C 386.064 265.512 385.121 270.351 384.538 273.307 C 383.954 276.264 383.255 279.754 382.986 281.066 C 382.715 282.376 382.495 283.585 382.495 283.752 L 382.495 284.057 L 389.899 284.057 Z M 565.658 284.057 L 573.228 284.057 L 573.228 281.741 L 573.228 279.423 L 574.1 273.677 C 574.581 270.518 575.372 265.512 575.86 262.557 C 576.348 259.6 576.955 255.855 577.21 254.233 C 577.466 252.612 578.142 249.101 578.713 246.431 C 579.286 243.76 579.999 240.874 580.3 240.015 C 580.601 239.157 580.849 238.256 580.852 238.014 C 580.856 237.772 581.501 236.214 582.286 234.552 L 583.715 231.529 L 585.601 229.024 L 587.486 226.52 L 589.549 224.969 C 590.683 224.115 592.508 222.984 593.604 222.453 L 595.596 221.488 L 599.93 221.518 L 604.265 221.549 L 605.972 222.096 L 607.678 222.644 L 607.966 222.466 L 608.253 222.288 L 608.269 221.182 C 608.276 220.573 608.647 218.309 609.093 216.149 L 609.904 212.223 L 608.992 211.866 C 608.491 211.67 607.301 211.264 606.347 210.964 L 604.613 210.417 L 601.492 210.426 L 598.371 210.433 L 595.827 211.329 L 593.283 212.223 L 591.373 213.375 L 589.464 214.527 L 586.98 217.128 L 584.497 219.728 L 583.163 221.746 C 582.43 222.856 581.784 223.714 581.728 223.653 C 581.672 223.593 582.071 221.28 582.614 218.515 C 583.157 215.749 583.609 213.135 583.617 212.706 L 583.632 211.925 L 577.216 211.925 L 570.801 211.925 L 570.801 212.147 C 570.801 212.268 570.481 214.492 570.09 217.088 C 569.699 219.685 568.913 224.696 568.346 228.225 C 567.777 231.753 566.845 237.449 566.273 240.883 C 565.702 244.316 564.84 249.232 564.358 251.807 C 563.877 254.381 563.022 258.907 562.458 261.863 C 561.894 264.82 560.968 269.58 560.4 272.441 C 559.832 275.301 559.078 279.086 558.727 280.85 L 558.087 284.057 L 565.658 284.057 Z M 230.107 199.434 L 232.211 199.441 L 233.885 198.871 L 235.56 198.301 L 237.041 196.798 L 238.523 195.296 L 239.302 193.293 L 240.083 191.291 L 240.11 188.343 L 240.138 185.397 L 239.445 184.245 L 238.751 183.094 L 237.544 182.347 L 236.336 181.599 L 233.729 181.599 L 231.122 181.599 L 229.347 182.394 L 227.572 183.188 L 226.542 184.292 L 225.512 185.397 L 224.702 187.304 L 223.893 189.211 L 223.74 192.182 L 223.588 195.153 L 224.34 196.63 L 225.094 198.106 L 226.548 198.766 L 228.001 199.425 L 230.107 199.434 Z" style="fill: rgb(179, 19, 27);"/>
7
+ </svg>
img/credit-cards/jcb.svg ADDED
@@ -0,0 +1,29 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?xml version="1.0" encoding="UTF-8" standalone="no"?>
2
+ <svg width="750px" height="471px" viewBox="0 0 750 471" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:sketch="http://www.bohemiancoding.com/sketch/ns">
3
+ <!-- Generator: Sketch 3.3.1 (12005) - http://www.bohemiancoding.com/sketch -->
4
+ <title>Slice 1</title>
5
+ <desc>Created with Sketch.</desc>
6
+ <defs>
7
+ <linearGradient x1="0.031607858%" y1="49.9998574%" x2="99.9743153%" y2="49.9998574%" id="linearGradient-1">
8
+ <stop stop-color="#007B40" offset="0%"></stop>
9
+ <stop stop-color="#55B330" offset="100%"></stop>
10
+ </linearGradient>
11
+ <linearGradient x1="0.471693172%" y1="49.999826%" x2="99.9860086%" y2="49.999826%" id="linearGradient-2">
12
+ <stop stop-color="#1D2970" offset="0%"></stop>
13
+ <stop stop-color="#006DBA" offset="100%"></stop>
14
+ </linearGradient>
15
+ <linearGradient x1="0.113880772%" y1="50.0008964%" x2="99.9860003%" y2="50.0008964%" id="linearGradient-3">
16
+ <stop stop-color="#6E2B2F" offset="0%"></stop>
17
+ <stop stop-color="#E30138" offset="100%"></stop>
18
+ </linearGradient>
19
+ </defs>
20
+ <g id="Page-1" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd" sketch:type="MSPage">
21
+ <g id="jcb" sketch:type="MSLayerGroup">
22
+ <rect id="Rectangle-1" fill="#0E4C96" sketch:type="MSShapeGroup" x="0" y="0" width="750" height="471" rx="40"></rect>
23
+ <path d="M617.243183,346.766281 C617.243183,388.380887 583.514892,422.125974 541.88349,422.125974 L132.756823,422.125974 L132.756823,124.244916 C132.756823,82.6186826 166.489851,48.8744567 208.121683,48.8744567 L617.242752,48.874026 L617.242752,346.766281 L617.243183,346.766281 L617.243183,346.766281 Z" id="path3494" fill="#FFFFFF" sketch:type="MSShapeGroup"></path>
24
+ <path d="M483.858874,242.044797 C495.542699,242.298285 507.296188,241.528806 518.936004,242.444883 C530.723244,244.645678 533.563915,262.487874 523.09234,268.332511 C515.950746,272.182115 507.459496,269.764696 499.713328,270.446208 L483.858874,270.446208 L483.858874,242.044797 L483.858874,242.044797 Z M525.691826,209.900487 C528.288491,219.064679 519.453903,227.292118 510.625917,226.030566 L483.858874,226.030566 C484.043758,217.388441 483.491345,208.008973 484.131053,199.821663 C494.854942,200.123386 505.679576,199.205849 516.340394,200.301853 C520.921799,201.451558 524.753935,205.217712 525.691826,209.900487 L525.691826,209.900487 Z M590.120412,73.9972254 C590.617872,91.498454 590.191471,109.92365 590.33359,127.780192 C590.299137,200.376358 590.405942,272.974174 590.278896,345.569303 C589.81042,372.776592 565.696524,396.413678 538.678749,396.956694 C511.63292,397.068451 484.584297,396.972628 457.537396,397.004497 L457.537396,287.253291 C487.007,287.099803 516.49604,287.561 545.953521,287.021594 C559.62072,286.162769 574.586027,277.145695 575.22328,262.107374 C576.833661,247.005483 562.592128,236.557185 549.071096,234.905684 C543.872773,234.770542 544.027132,233.390846 549.071096,232.788972 C561.96307,230.002483 572.090675,216.655787 568.296786,203.290229 C565.06052,189.232374 549.523839,183.79142 536.600366,183.817768 C510.248548,183.638612 483.891299,183.792359 457.537396,183.74111 C457.708585,163.252408 457.182916,142.740653 457.82271,122.267364 C459.910361,95.5513766 484.628603,73.5195319 511.269759,73.997656 C537.553166,73.9973692 563.837737,73.9982301 590.120412,73.9972254 L590.120412,73.9972254 Z" id="path3496" fill="url(#linearGradient-1)" sketch:type="MSShapeGroup"></path>
25
+ <path d="M159.740429,125.040498 C160.413689,97.8766592 184.628619,74.4290299 211.614797,74.0325398 C238.559493,73.9499686 265.506204,74.0209119 292.451671,73.9972254 C292.37764,164.882488 292.599905,255.773672 292.340301,346.655222 C291.302298,373.488802 267.350548,396.488661 240.661356,396.962292 C213.665015,397.060957 186.666275,396.976074 159.669012,397.004497 L159.669012,283.550875 C185.891623,289.745491 213.391138,292.382518 240.142406,288.272242 C256.134509,285.697368 273.629935,277.848026 279.044261,261.257567 C283.030122,247.066267 280.785723,232.131602 281.378027,217.566465 L281.378027,183.741541 L235.081246,183.741541 C234.873106,206.112145 235.507258,228.522447 234.746146,250.867107 C233.49785,264.601214 219.900147,273.326996 206.946428,272.861801 C190.879747,273.030535 159.04755,261.221796 159.04755,261.221796 C158.967492,219.3048 159.514314,166.814385 159.740429,125.040498 L159.740429,125.040498 Z" id="path3498" fill="url(#linearGradient-2)" sketch:type="MSShapeGroup"></path>
26
+ <path d="M309.719995,197.390136 C307.285788,197.90738 309.229141,189.089459 308.606298,185.743964 C308.772233,164.593637 308.260045,143.420951 308.889718,122.285827 C310.972541,95.4570827 335.881262,73.3701105 362.628748,73.997656 L441.39456,73.997656 C441.320658,164.882346 441.542493,255.77294 441.283406,346.653934 C440.244412,373.488027 416.291344,396.487102 389.602087,396.962292 C362.604605,397.061991 335.604707,396.976504 308.606298,397.004928 L308.606298,272.707624 C327.04641,287.835846 352.105738,290.192248 375.077953,290.233484 C392.39501,290.227455 409.611861,287.557865 426.428143,283.562934 L426.428143,260.790297 C407.474658,270.236609 385.194808,276.235815 364.184745,270.807966 C349.529051,267.157367 338.89089,252.996683 339.128513,237.872204 C337.43001,222.143684 346.652631,205.536885 362.110237,200.860855 C381.300923,194.852545 402.217787,199.448454 420.206344,207.258795 C424.060526,209.27695 427.97066,211.780342 426.428143,205.338044 L426.428143,187.438358 C396.343581,180.280951 364.326644,177.646405 334.099438,185.433619 C325.351193,187.901774 316.82819,191.644647 309.719995,197.390136 L309.719995,197.390136 Z" id="path3500" fill="url(#linearGradient-3)" sketch:type="MSShapeGroup"></path>
27
+ </g>
28
+ </g>
29
+ </svg>
img/credit-cards/maestro.svg ADDED
@@ -0,0 +1,29 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?xml version="1.0" encoding="UTF-8" standalone="no"?>
2
+ <svg width="750px" height="471px" viewBox="0 0 750 471" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:sketch="http://www.bohemiancoding.com/sketch/ns">
3
+ <!-- Generator: Sketch 3.3.1 (12005) - http://www.bohemiancoding.com/sketch -->
4
+ <title>Slice 1</title>
5
+ <desc>Created with Sketch.</desc>
6
+ <defs></defs>
7
+ <g id="Page-1" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd" sketch:type="MSPage">
8
+ <g id="maestro" sketch:type="MSLayerGroup">
9
+ <rect id="Rectangle-1" fill="#000000" sketch:type="MSShapeGroup" x="0" y="0" width="750" height="471" rx="40"></rect>
10
+ <path d="M675.000003,235.50625 C675.000003,334.639584 594.650002,415.002085 495.516668,415.002085 C396.395834,415.002085 316.0375,334.639584 316.0375,235.50625 C316.0375,136.364582 396.395834,55.997915 495.516668,55.997915 C594.650002,55.997915 675.000003,136.364582 675.000003,235.50625" id="Fill-1" fill="#D9222A" sketch:type="MSShapeGroup"></path>
11
+ <path d="M356.870834,349.489584 C351.9125,343.477084 347.345834,337.131251 343.195834,330.481251 L406.808334,330.481251 C410.625001,324.385417 414.070834,318.039584 417.150001,311.46875 L332.858333,311.46875 C329.9875,305.31875 327.433333,298.977084 325.2625,292.46875 L424.737501,292.46875 C430.725001,274.564583 433.966668,255.41875 433.966668,235.50625 C433.966668,222.460416 432.575001,209.74375 429.937501,197.493749 L320.075,197.493749 C321.466667,191.014583 323.216667,184.677083 325.283333,178.485416 L424.725001,178.485416 C422.541667,171.977083 420.004167,165.635416 417.133334,159.481249 L332.879167,159.481249 C335.954167,152.918749 339.408333,146.577082 343.216667,140.472916 L406.787501,140.472916 C402.641667,133.843749 398.062501,127.497916 393.116667,121.481249 L356.891667,121.481249 C362.4625,114.714582 368.520834,108.364582 375.004167,102.481249 C343.15,73.5979152 300.866667,55.997915 254.487499,55.997915 C155.358332,55.997915 74.999998,136.364582 74.999998,235.50625 C74.999998,334.639584 155.358332,415.002085 254.487499,415.002085 C300.875,415.002085 343.154167,397.406251 375.004167,368.527084 C381.5,362.635417 387.562501,356.268751 393.137501,349.489584 L356.870834,349.489584" id="Fill-2" fill="#0097D0" sketch:type="MSShapeGroup"></path>
12
+ <path d="M651.075003,335.543751 C651.075003,332.343751 653.670836,329.747917 656.875003,329.747917 C660.075003,329.747917 662.666669,332.343751 662.666669,335.543751 C662.666669,338.747917 660.075003,341.343751 656.875003,341.343751 C653.670836,341.343751 651.075003,338.747917 651.075003,335.543751 L651.075003,335.543751 L651.075003,335.543751 Z M656.875003,339.952084 C659.308336,339.952084 661.279169,337.985417 661.279169,335.543751 C661.279169,333.110417 659.308336,331.147917 656.875003,331.147917 C654.441669,331.147917 652.466669,333.110417 652.466669,335.543751 C652.466669,337.985417 654.441669,339.952084 656.875003,339.952084 L656.875003,339.952084 L656.875003,339.952084 Z M656.087503,338.089584 L654.904169,338.089584 L654.904169,332.997917 L657.054169,332.997917 C657.500003,332.997917 657.958336,333.002084 658.354169,333.256251 C658.770836,333.539584 659.000003,334.031251 659.000003,334.527084 C659.000003,335.110417 658.662503,335.639584 658.120836,335.843751 L659.054169,338.089584 L657.737503,338.089584 L656.962503,336.081251 L656.087503,336.081251 L656.087503,338.089584 L656.087503,338.089584 Z M656.087503,335.210417 L656.745836,335.210417 C656.991669,335.210417 657.250003,335.227084 657.470836,335.110417 C657.666669,334.981251 657.770836,334.743751 657.770836,334.518751 C657.770836,334.331251 657.645836,334.102084 657.483336,334.006251 C657.270836,333.881251 656.941669,333.906251 656.720836,333.906251 L656.087503,333.906251 L656.087503,335.210417 L656.087503,335.210417 Z" id="Fill-3" fill="#000000" sketch:type="MSShapeGroup"></path>
13
+ <path d="M372.445834,284.00625 C364.775,286.039584 357.358334,287.03125 349.516667,287.014584 C324.5,286.989584 311.470833,275.597917 311.470833,253.814583 C311.470833,228.35625 328.058333,209.63125 350.570834,209.63125 C368.9875,209.63125 380.745834,220.13125 380.745834,236.577083 C380.745834,242.035417 379.95,247.347917 378,254.872917 L333.5125,254.872917 C331.929167,265.50625 339.7,270.177083 352.925,270.177083 C360.85,270.177083 368.016667,268.752083 375.95,265.564583 L372.445834,284.00625 L372.445834,284.00625 Z M360.483334,239.85625 C360.483334,238.247916 362.958334,226.822916 350.083334,226.572916 C342.975,226.572916 337.875,231.297916 335.8125,239.85625 L360.483334,239.85625 L360.483334,239.85625 Z" id="Fill-4" fill="#000000" sketch:type="MSShapeGroup"></path>
14
+ <path d="M387.516667,234.864583 C387.516667,244.26875 392.812501,250.764583 404.845834,255.602083 C414.045834,259.372917 415.495834,260.460417 415.495834,263.822917 C415.495834,268.485417 411.429167,270.627083 402.404167,270.56875 C395.625001,270.51875 389.441667,269.697917 382.141667,267.672917 L378.9125,284.827084 C385.400001,286.33125 394.500001,286.827084 402.562501,287.014584 C426.587501,287.014584 437.679168,279.147917 437.679168,262.147917 C437.679168,251.93125 433.054168,245.914583 421.645834,241.435417 C412.108334,237.627083 410.987501,236.797916 410.987501,233.352083 C410.987501,229.302083 414.766667,227.252083 422.137501,227.252083 C426.600001,227.252083 432.716668,227.664583 438.516668,228.360416 L441.775001,211.11875 C435.862501,210.29375 426.891668,209.635416 421.700001,209.635416 C396.250001,209.635416 387.441667,221.09375 387.516667,234.864583" id="Fill-5" fill="#000000" sketch:type="MSShapeGroup"></path>
15
+ <path d="M299.275,285.785417 L280.6125,285.785417 L281.058333,277.964583 C275.366666,284.135417 267.7875,287.00625 257.499999,287.00625 C245.324999,287.00625 236.983333,278.68125 236.983333,266.710417 C236.983333,248.514583 251.483333,238.01875 276.4125,238.01875 C278.975,238.01875 282.233333,238.210416 285.579166,238.58125 C286.270833,236.147916 286.458333,235.102083 286.458333,233.772916 C286.458333,228.79375 282.5375,226.960416 272.045833,226.960416 C261.704166,227.002083 254.724999,228.53125 248.249999,230.272916 L251.437499,213.572916 C262.633333,210.727083 269.966666,209.63125 278.2625,209.63125 C297.566666,209.63125 307.7625,217.197916 307.7625,231.427083 C307.929167,235.222916 306.604167,242.839583 305.941667,246.172917 C305.183333,251.027083 299.833333,279.147917 299.275,285.785417 L299.275,285.785417 L299.275,285.785417 Z M282.895833,252.59375 C280.529166,252.352083 279.5,252.28125 277.883333,252.28125 C265.154166,252.28125 258.7,256.06875 258.7,263.547917 C258.7,268.239583 261.85,271.18125 266.758333,271.18125 C275.904166,271.18125 282.508333,263.53125 282.895833,252.59375 L282.895833,252.59375 L282.895833,252.59375 Z" id="Fill-6" fill="#000000" sketch:type="MSShapeGroup"></path>
16
+ <path d="M477.004168,284.60625 C470.879168,286.285417 466.108334,287.014584 460.945834,287.014584 C449.512501,287.014584 443.270834,281.172917 443.270834,270.764583 C442.912501,267.90625 445.704168,254.70625 446.337501,251.027083 C446.970834,247.335417 456.875001,193.535416 456.875001,193.535416 L479.087501,193.535416 L475.725001,211.335416 L487.116668,211.335416 L484.020835,229.50625 L472.579168,229.50625 C472.579168,229.50625 466.300001,261.035417 466.300001,263.439583 C466.300001,267.264583 468.616668,268.927083 473.933335,268.927083 C476.479168,268.927083 478.441668,268.689583 479.962501,268.235417 L477.004168,284.60625" id="Fill-7" fill="#000000" sketch:type="MSShapeGroup"></path>
17
+ <path d="M576.250002,209.63125 C559.970835,209.63125 547.250002,216.33125 539.862502,227.522916 L546.275002,210.927083 C534.458335,206.589583 526.841668,212.777083 519.950002,221.577083 C519.950002,221.577083 518.795835,223.039583 517.650002,224.377083 L517.650002,211.327083 L496.791668,211.327083 C493.966668,234.35625 488.970835,257.70625 485.062501,280.772917 L484.120835,285.79375 L506.558335,285.79375 C508.683335,274.085417 510.433335,264.58125 512.175002,257.00625 C516.941668,236.21875 524.962502,229.864583 537.004168,232.672916 C534.225002,238.652083 532.700002,245.564583 532.700002,253.227083 C532.700002,271.80625 542.791668,287.014584 567.850002,287.014584 C593.137502,287.014584 611.445836,273.50625 611.445836,242.70625 C611.445836,224.127083 599.245836,209.63125 576.250002,209.63125 L576.250002,209.63125 L576.250002,209.63125 Z M569.720835,268.947917 C561.795835,269.072917 556.991669,262.422917 556.991669,252.477083 C556.991669,240.685417 564.004169,227.364583 575.266669,227.364583 C584.354169,227.364583 587.466669,234.56875 587.466669,242.24375 C587.466669,259.022917 580.591669,268.947917 569.720835,268.947917 L569.720835,268.947917 L569.720835,268.947917 Z" id="Fill-8" fill="#000000" sketch:type="MSShapeGroup"></path>
18
+ <path d="M226.529166,285.79375 L204.187499,285.79375 L217.466666,215.839583 L186.895832,285.79375 L166.529165,285.79375 L162.804165,216.24375 L149.483332,285.79375 L129.212498,285.79375 L146.479165,194.797916 L181.391666,194.797916 L184.304166,245.522917 L206.420832,194.797916 L244.141666,194.797916 L226.529166,285.79375" id="Fill-9" fill="#000000" sketch:type="MSShapeGroup"></path>
19
+ <path d="M613.150002,274.385417 C613.150002,271.189583 615.745836,268.589583 618.945836,268.589583 C622.150002,268.589583 624.741669,271.189583 624.741669,274.385417 C624.741669,277.59375 622.150002,280.189583 618.945836,280.189583 C615.745836,280.189583 613.150002,277.59375 613.150002,274.385417 L613.150002,274.385417 L613.150002,274.385417 Z M618.945836,278.797917 C621.379169,278.797917 623.354169,276.81875 623.354169,274.385417 C623.354169,271.952083 621.379169,269.98125 618.945836,269.98125 C616.512502,269.98125 614.537502,271.952083 614.537502,274.385417 C614.537502,276.81875 616.512502,278.797917 618.945836,278.797917 L618.945836,278.797917 L618.945836,278.797917 Z M618.162502,276.93125 L616.975002,276.93125 L616.975002,271.847917 L619.125002,271.847917 C619.575002,271.847917 620.033336,271.847917 620.429169,272.097917 C620.837502,272.377083 621.075002,272.864583 621.075002,273.36875 C621.075002,273.947917 620.737502,274.485417 620.191669,274.685417 L621.125002,276.93125 L619.808336,276.93125 L619.037502,274.922917 L618.162502,274.922917 L618.162502,276.93125 L618.162502,276.93125 Z M618.162502,274.04375 L618.820836,274.04375 C619.062502,274.04375 619.325002,274.060417 619.545836,273.947917 C619.741669,273.814583 619.841669,273.589583 619.841669,273.360417 C619.841669,273.164583 619.720836,272.94375 619.558336,272.847917 C619.345836,272.71875 619.016669,272.752083 618.795836,272.752083 L618.162502,272.752083 L618.162502,274.04375 L618.162502,274.04375 Z" id="Fill-10" fill="#FFFFFF" sketch:type="MSShapeGroup"></path>
20
+ <path d="M378.054167,278.397917 C370.3875,280.43125 362.966667,281.427084 355.129167,281.410417 C330.1125,281.385417 317.083333,269.989583 317.083333,248.202083 C317.083333,222.752083 333.6625,204.022916 356.179167,204.022916 C374.6,204.022916 386.354167,214.51875 386.354167,230.964583 C386.354167,236.43125 385.554167,241.735417 383.612501,249.264583 L339.125,249.264583 C337.541667,259.89375 345.304167,264.572917 358.533334,264.572917 C366.458334,264.572917 373.620834,263.147917 381.5625,259.95625 L378.054167,278.397917 L378.054167,278.397917 Z M366.091667,234.247916 C366.091667,232.64375 368.5625,221.214583 355.691667,220.96875 C348.583334,220.96875 343.4875,225.697916 341.420833,234.247916 L366.091667,234.247916 L366.091667,234.247916 Z" id="Fill-11" fill="#FFFFFF" sketch:type="MSShapeGroup"></path>
21
+ <path d="M393.129167,229.252083 C393.129167,238.660416 398.416667,245.152083 410.454167,249.997917 C419.658334,253.764583 421.104167,254.85625 421.104167,258.210417 C421.104167,262.877083 417.037501,265.01875 408.016667,264.960417 C401.233334,264.914583 395.050001,264.089583 387.754167,262.064583 L384.516667,279.210417 C391.008334,280.727083 400.112501,281.222917 408.170834,281.410417 C432.195834,281.410417 443.291668,273.539583 443.291668,256.539583 C443.291668,246.322917 438.662501,240.302083 427.250001,235.827083 C417.712501,232.01875 416.595834,231.189583 416.595834,227.74375 C416.595834,223.69375 420.379167,221.64375 427.741668,221.64375 C432.212501,221.64375 438.325001,222.060416 444.129168,222.75625 L447.379168,205.510416 C441.466668,204.685416 432.500001,204.027083 427.312501,204.027083 C401.854167,204.027083 393.050001,215.48125 393.129167,229.252083" id="Fill-12" fill="#FFFFFF" sketch:type="MSShapeGroup"></path>
22
+ <path d="M304.8875,280.18125 L286.220833,280.18125 L286.670833,272.360417 C280.975,278.51875 273.395833,281.39375 263.1125,281.39375 C250.937499,281.39375 242.591666,273.06875 242.591666,261.10625 C242.591666,242.902083 257.087499,232.410416 282.020833,232.410416 C284.583333,232.410416 287.8375,232.602083 291.191666,232.972916 C291.883333,230.539583 292.066666,229.497916 292.066666,228.164583 C292.066666,223.18125 288.15,221.352083 277.658333,221.352083 C267.316666,221.39375 260.3375,222.927083 253.862499,224.664583 L257.045833,207.96875 C268.245833,205.11875 275.575,204.022916 283.875,204.022916 C303.179167,204.022916 313.370833,211.589583 313.370833,225.814583 C313.5375,229.614583 312.2125,237.227083 311.554167,240.56875 C310.791667,245.41875 305.441667,273.539583 304.8875,280.18125 L304.8875,280.18125 L304.8875,280.18125 Z M288.5,246.985417 C286.141666,246.739583 285.108333,246.672917 283.4875,246.672917 C270.766666,246.672917 264.308333,250.460417 264.308333,257.939583 C264.308333,262.635417 267.4625,265.572917 272.3625,265.572917 C281.516666,265.572917 288.120833,257.91875 288.5,246.985417 L288.5,246.985417 L288.5,246.985417 Z" id="Fill-13" fill="#FFFFFF" sketch:type="MSShapeGroup"></path>
23
+ <path d="M482.608335,279.002083 C476.487501,280.677083 471.712501,281.410417 466.554168,281.410417 C455.120834,281.410417 448.883334,275.564583 448.883334,265.15625 C448.520834,262.302083 451.316668,249.097917 451.945834,245.41875 C452.579168,241.727083 462.483334,187.927083 462.483334,187.927083 L484.691668,187.927083 L481.337501,205.727083 L492.729168,205.727083 L489.633335,223.897916 L478.191668,223.897916 C478.191668,223.897916 471.908335,255.427083 471.908335,257.83125 C471.908335,261.65625 474.229168,263.310417 479.541668,263.310417 C482.083335,263.310417 484.050001,263.08125 485.570835,262.61875 L482.608335,279.002083" id="Fill-14" fill="#FFFFFF" sketch:type="MSShapeGroup"></path>
24
+ <path d="M593.079169,236.635416 C593.079169,253.410417 586.200002,263.34375 575.325002,263.34375 C567.404169,263.45625 562.600002,256.81875 562.600002,246.86875 C562.600002,235.077083 569.608335,221.75625 580.870835,221.75625 C589.962502,221.75625 593.079169,228.96875 593.079169,236.635416 L593.079169,236.635416 L593.079169,236.635416 Z M617.058336,237.102083 C617.058336,218.522916 604.850002,204.022916 581.862502,204.022916 C555.412502,204.022916 538.312502,221.647916 538.312502,247.61875 C538.312502,266.197917 548.395835,281.410417 573.462502,281.410417 C598.750002,281.410417 617.058336,267.897917 617.058336,237.102083 L617.058336,237.102083 L617.058336,237.102083 Z" id="Fill-15" fill="#FFFFFF" sketch:type="MSShapeGroup"></path>
25
+ <path d="M502.395835,205.71875 C499.575001,228.747916 494.579168,252.09375 490.675001,275.16875 L489.729168,280.189583 L512.162502,280.189583 C520.250002,235.63125 522.962502,222.935416 539.904168,227.40625 L548.054168,206.31875 C536.237502,201.98125 528.629168,208.172916 521.745835,216.977083 C522.366668,213.014583 523.537502,209.19375 523.254168,205.71875 L502.395835,205.71875" id="Fill-16" fill="#FFFFFF" sketch:type="MSShapeGroup"></path>
26
+ <path d="M232.137499,280.189583 L209.799999,280.189583 L223.074999,210.23125 L192.499999,280.189583 L172.137499,280.189583 L168.412499,210.635416 L155.091665,280.189583 L134.820832,280.189583 L152.083332,189.189583 L187.004166,189.189583 L188.849999,245.522917 L213.424999,189.189583 L249.749999,189.189583 L232.137499,280.189583" id="Fill-17" fill="#FFFFFF" sketch:type="MSShapeGroup"></path>
27
+ </g>
28
+ </g>
29
+ </svg>
img/credit-cards/mastercard.svg ADDED
@@ -0,0 +1,34 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?xml version="1.0" encoding="UTF-8" standalone="no"?>
2
+ <svg width="750px" height="471px" viewBox="0 0 750 471" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:sketch="http://www.bohemiancoding.com/sketch/ns">
3
+ <!-- Generator: Sketch 3.3.1 (12005) - http://www.bohemiancoding.com/sketch -->
4
+ <title>Slice 1</title>
5
+ <desc>Created with Sketch.</desc>
6
+ <defs></defs>
7
+ <g id="Page-1" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd" sketch:type="MSPage">
8
+ <g id="mastercard" sketch:type="MSLayerGroup">
9
+ <rect id="Rectangle-1" fill="#000000" sketch:type="MSShapeGroup" x="0" y="0" width="750" height="471" rx="40"></rect>
10
+ <path d="M434.008334,235.5 C434.008334,334.641668 353.6375,415.004169 254.499999,415.004169 C155.362498,415.004169 74.9999973,334.641668 74.9999973,235.5 C74.9999973,136.366666 155.362498,55.9958324 254.499999,55.9958324 C353.6375,55.9958324 434.008334,136.366666 434.008334,235.5" id="Fill-1" fill="#D9222A" sketch:type="MSShapeGroup"></path>
11
+ <path d="M495.491667,55.9958324 C449.1125,55.9958324 406.85,73.5916658 374.991666,102.462499 C368.504166,108.345833 362.445833,114.7 356.866666,121.458333 L393.133333,121.458333 C398.091667,127.4875 402.658333,133.829166 406.816667,140.470833 L343.183333,140.470833 C339.370833,146.575 335.908333,152.916666 332.841666,159.479167 L417.154167,159.479167 C420.033333,165.6375 422.575,171.975 424.754167,178.483333 L325.241666,178.483333 C323.166666,184.675 321.420833,191.0125 320.024999,197.491667 L429.966667,197.491667 C432.604167,209.741667 434.008334,222.458334 434.008334,235.5 C434.008334,255.433334 430.754167,274.612501 424.754167,292.520834 L325.241666,292.520834 C327.416666,299.033334 329.958333,305.375001 332.837499,311.529168 L417.154167,311.529168 C414.079167,318.091668 410.625,324.433335 406.808333,330.541668 L343.183333,330.541668 C347.3375,337.170835 351.9125,343.520835 356.866666,349.537501 L393.125,349.537501 C387.554167,356.308335 381.491666,362.670835 374.995833,368.550002 C406.854167,397.416668 449.1125,415.004169 495.491667,415.004169 C594.629168,415.004169 675.000002,334.641668 675.000002,235.5 C675.000002,136.370833 594.629168,55.9958324 495.491667,55.9958324" id="Fill-2" fill="#EE9F2D" sketch:type="MSShapeGroup"></path>
12
+ <path d="M651.075002,335.558335 C651.075002,332.358335 653.666669,329.758335 656.870835,329.758335 C660.075002,329.758335 662.666669,332.358335 662.666669,335.558335 C662.666669,338.758335 660.075002,341.358335 656.870835,341.358335 C653.666669,341.358335 651.075002,338.758335 651.075002,335.558335 L651.075002,335.558335 L651.075002,335.558335 Z M656.870835,339.966668 C659.304169,339.966668 661.279169,337.991668 661.279169,335.558335 C661.279169,333.120835 659.304169,331.154168 656.870835,331.154168 C654.433335,331.154168 652.466669,333.120835 652.466669,335.558335 C652.466669,337.991668 654.433335,339.966668 656.870835,339.966668 L656.870835,339.966668 L656.870835,339.966668 Z M656.087502,338.108335 L654.900002,338.108335 L654.900002,333.012501 L657.050002,333.012501 C657.500002,333.012501 657.958335,333.012501 658.354169,333.266668 C658.766669,333.545835 659.000002,334.037501 659.000002,334.545835 C659.000002,335.116668 658.662502,335.650001 658.116669,335.858335 L659.054169,338.108335 L657.737502,338.108335 L656.958335,336.091668 L656.087502,336.091668 L656.087502,338.108335 L656.087502,338.108335 Z M656.087502,335.216668 L656.745835,335.216668 C656.991669,335.216668 657.250002,335.237501 657.470835,335.116668 C657.666669,334.991668 657.766669,334.758335 657.766669,334.533335 C657.766669,334.337501 657.645835,334.112501 657.479169,334.016668 C657.270835,333.887501 656.941669,333.916668 656.720835,333.916668 L656.087502,333.916668 L656.087502,335.216668 L656.087502,335.216668 Z" id="Fill-3" fill="#000000" sketch:type="MSShapeGroup"></path>
13
+ <path d="M212.587498,255.154167 C210.541665,254.916667 209.641665,254.854167 208.237498,254.854167 C197.191665,254.854167 191.599998,258.641667 191.599998,266.120834 C191.599998,270.733334 194.329165,273.666667 198.587498,273.666667 C206.524998,273.666667 212.245832,266.108334 212.587498,255.154167 L212.587498,255.154167 L212.587498,255.154167 Z M226.758332,288.150001 L210.612498,288.150001 L210.983332,280.475001 C206.058332,286.541668 199.487498,289.425001 190.558332,289.425001 C179.995832,289.425001 172.754165,281.175001 172.754165,269.195834 C172.754165,251.170834 185.349998,240.654167 206.970832,240.654167 C209.179165,240.654167 212.012498,240.854167 214.912498,241.225001 C215.516665,238.783334 215.674998,237.7375 215.674998,236.425 C215.674998,231.516667 212.279165,229.6875 203.174998,229.6875 C193.641665,229.579167 185.779165,231.958334 182.549998,233.020834 C182.754165,231.791667 185.249998,216.3625 185.249998,216.3625 C194.962498,213.516667 201.366665,212.445834 208.574998,212.445834 C225.308332,212.445834 234.170832,219.958334 234.154165,234.158334 C234.187499,237.9625 233.558332,242.658334 232.574999,248.829167 C230.883332,259.558334 227.254165,282.545834 226.758332,288.150001 L226.758332,288.150001 L226.758332,288.150001 Z" id="Fill-4" fill="#000000" sketch:type="MSShapeGroup"></path>
14
+ <path d="M164.599998,288.150001 L145.112498,288.150001 L156.274998,218.154167 L131.349998,288.150001 L118.070831,288.150001 L116.429164,218.554167 L104.695831,288.150001 L86.4541641,288.150001 L101.691664,197.095833 L129.712498,197.095833 L131.412498,248.062501 L148.504165,197.095833 L179.670832,197.095833 L164.599998,288.150001" id="Fill-5" fill="#000000" sketch:type="MSShapeGroup"></path>
15
+ <path d="M519.575001,255.154167 C517.537501,254.916667 516.633334,254.854167 515.233334,254.854167 C504.191667,254.854167 498.600001,258.641667 498.600001,266.120834 C498.600001,270.733334 501.325001,273.666667 505.583334,273.666667 C513.520834,273.666667 519.245834,266.108334 519.575001,255.154167 L519.575001,255.154167 L519.575001,255.154167 Z M533.758334,288.150001 L517.612501,288.150001 L517.979168,280.475001 C513.054168,286.541668 506.479167,289.425001 497.558334,289.425001 C486.991667,289.425001 479.758334,281.175001 479.758334,269.195834 C479.758334,251.170834 492.345834,240.654167 513.970834,240.654167 C516.179168,240.654167 519.008334,240.854167 521.904168,241.225001 C522.508334,238.783334 522.666668,237.7375 522.666668,236.425 C522.666668,231.516667 519.275001,229.6875 510.170834,229.6875 C500.637501,229.579167 492.783334,231.958334 489.541667,233.020834 C489.745834,231.791667 492.250001,216.3625 492.250001,216.3625 C501.962501,213.516667 508.362501,212.445834 515.562501,212.445834 C532.304168,212.445834 541.166668,219.958334 541.150001,234.158334 C541.183334,237.9625 540.554168,242.658334 539.570834,248.829167 C537.887501,259.558334 534.250001,282.545834 533.758334,288.150001 L533.758334,288.150001 L533.758334,288.150001 Z" id="Fill-6" fill="#000000" sketch:type="MSShapeGroup"></path>
16
+ <path d="M313.366666,287.025001 C308.033333,288.704168 303.874999,289.425001 299.366666,289.425001 C289.404166,289.425001 283.966666,283.700001 283.966666,273.158334 C283.824999,269.887501 285.399999,261.279167 286.637499,253.420834 C287.762499,246.504167 295.087499,202.891667 295.087499,202.891667 L314.458333,202.891667 L312.195833,214.1 L323.895833,214.1 L321.254166,231.895834 L309.512499,231.895834 C307.262499,245.979167 304.058333,263.520834 304.020833,265.845834 C304.020833,269.662501 306.058333,271.329167 310.691666,271.329167 C312.912499,271.329167 314.633333,271.104167 315.945833,270.629167 L313.366666,287.025001" id="Fill-7" fill="#000000" sketch:type="MSShapeGroup"></path>
17
+ <path d="M372.758333,286.425001 C366.104166,288.458334 359.683333,289.441668 352.879166,289.425001 C331.195833,289.404168 319.891666,278.079167 319.891666,256.391667 C319.891666,231.079167 334.270833,212.445834 353.791666,212.445834 C369.7625,212.445834 379.9625,222.879167 379.9625,239.241667 C379.9625,244.670834 379.2625,249.970834 377.575,257.454167 L338.999999,257.454167 C337.695833,268.195834 344.570833,272.670834 355.8375,272.670834 C362.770833,272.670834 369.025,271.241667 375.979166,268.008334 L372.758333,286.425001 L372.758333,286.425001 Z M361.870833,242.525001 C361.979166,240.983334 363.925,229.308334 352.858333,229.308334 C346.6875,229.308334 342.274999,234.0125 340.479166,242.525001 L361.870833,242.525001 L361.870833,242.525001 Z" id="Fill-8" fill="#000000" sketch:type="MSShapeGroup"></path>
18
+ <path d="M238.445832,237.508334 C238.445832,246.875001 242.987499,253.333334 253.287499,258.183334 C261.179166,261.891667 262.399999,262.991667 262.399999,266.354167 C262.399999,270.970834 258.920832,273.054167 251.208332,273.054167 C245.395832,273.054167 239.987499,272.145834 233.749999,270.133334 C233.749999,270.133334 231.187499,286.454168 231.070832,287.233334 C235.499999,288.200001 239.449999,289.095834 251.349999,289.425001 C271.912499,289.425001 281.408332,281.595834 281.408332,264.675001 C281.408332,254.500001 277.433332,248.529167 267.670832,244.041667 C259.499999,240.291667 258.562499,239.454167 258.562499,235.995834 C258.562499,231.991667 261.799999,229.95 268.099999,229.95 C271.924999,229.95 277.149999,230.358334 282.099999,231.0625 L284.874999,213.8875 C279.829166,213.0875 272.179166,212.445834 267.724999,212.445834 C245.924999,212.445834 238.379165,223.833334 238.445832,237.508334" id="Fill-9" fill="#000000" sketch:type="MSShapeGroup"></path>
19
+ <path d="M467.533334,214.391667 C472.945834,214.391667 477.991667,215.8125 484.945834,219.3125 L488.133334,199.55 C485.279167,198.429167 475.229167,191.85 466.716667,191.85 C453.675,191.85 442.65,198.320834 434.895834,209 C423.5875,205.254167 418.9375,212.825 413.2375,220.366667 L408.175,221.545834 C408.558333,219.0625 408.904167,216.595834 408.7875,214.1 L390.891667,214.1 C388.445833,237.016667 384.1125,260.229167 380.720833,283.175001 L379.8375,288.150001 L399.333333,288.150001 C402.5875,267.008334 404.370833,253.470834 405.454167,244.308334 L412.795833,240.225001 C413.891667,236.145834 417.325,234.766667 424.2125,234.933334 C423.3125,239.766667 422.829167,244.850001 422.829167,250.116667 C422.829167,274.341667 435.9,289.425001 456.879167,289.425001 C462.283334,289.425001 466.920834,288.712501 474.100001,286.766668 L477.529167,266.008334 C471.070834,269.187501 465.770834,270.683334 460.970834,270.683334 C449.641667,270.683334 442.7875,262.320834 442.7875,248.500001 C442.7875,228.45 452.983334,214.391667 467.533334,214.391667" id="Fill-10" fill="#000000" sketch:type="MSShapeGroup"></path>
20
+ <path d="M170.208331,282.741668 L150.716665,282.741668 L161.887498,212.754167 L136.962498,282.741668 L123.679164,282.741668 L122.037498,213.154167 L110.304164,282.741668 L92.0624975,282.741668 L107.299998,191.7 L135.320831,191.7 L136.108331,248.062501 L155.012498,191.7 L185.279165,191.7 L170.208331,282.741668" id="Fill-12" fill="#FFFFFF" sketch:type="MSShapeGroup"></path>
21
+ <path d="M632.520835,197.095833 L628.200002,223.404167 C622.870835,216.391667 617.145835,211.316667 609.587502,211.316667 C599.754168,211.316667 590.804168,218.770834 584.945835,229.741667 C576.787501,228.05 568.350001,225.179167 568.350001,225.179167 L568.345835,225.245834 C569.004168,219.1125 569.266668,215.370834 569.208335,214.1 L551.308334,214.1 C548.870834,237.016667 544.537501,260.229167 541.150001,283.175001 L540.258334,288.150001 L559.750001,288.150001 C562.383335,271.054167 564.400001,256.858334 565.883335,245.600001 C572.541668,239.583334 575.875001,234.333334 582.604168,234.683334 C579.625001,241.887501 577.879168,250.187501 577.879168,258.700001 C577.879168,277.212501 587.245835,289.425001 601.412502,289.425001 C608.554168,289.425001 614.033335,286.962501 619.379168,281.254168 L618.466668,288.137501 L636.900002,288.137501 L651.741669,197.095833 L632.520835,197.095833 L632.520835,197.095833 Z M608.150002,271.037501 C601.516668,271.037501 598.166668,266.129167 598.166668,256.441667 C598.166668,241.887501 604.437502,231.566667 613.279168,231.566667 C619.975002,231.566667 623.600002,236.670834 623.600002,246.075001 C623.600002,260.754167 617.229168,271.037501 608.150002,271.037501 L608.150002,271.037501 L608.150002,271.037501 Z" id="Fill-11" fill="#000000" sketch:type="MSShapeGroup"></path>
22
+ <path d="M218.191665,249.758334 C216.149998,249.520834 215.245832,249.458334 213.845832,249.458334 C202.799998,249.458334 197.212498,253.245834 197.212498,260.725001 C197.212498,265.329167 199.941665,268.270834 204.191665,268.270834 C212.137498,268.270834 217.858332,260.712501 218.191665,249.758334 L218.191665,249.758334 L218.191665,249.758334 Z M232.370832,282.741668 L216.224998,282.741668 L216.591665,275.079167 C211.670832,281.133334 205.091665,284.029168 196.170832,284.029168 C185.604165,284.029168 178.366665,275.779167 178.366665,263.800001 C178.366665,245.766667 190.958332,235.258334 212.583332,235.258334 C214.791665,235.258334 217.624998,235.458334 220.520832,235.829167 C221.124999,233.3875 221.283332,232.341667 221.283332,231.020834 C221.283332,226.1125 217.891665,224.291667 208.787498,224.291667 C199.249998,224.183334 191.391665,226.5625 188.158332,227.6125 C188.362498,226.3875 190.858332,210.975 190.858332,210.975 C200.566665,208.116667 206.979165,207.045834 214.179165,207.045834 C230.916665,207.045834 239.783332,214.5625 239.766665,228.75 C239.795832,232.570834 239.162499,237.2625 238.183332,243.425001 C236.495832,254.150001 232.862499,277.150001 232.370832,282.741668 L232.370832,282.741668 L232.370832,282.741668 Z" id="Fill-13" fill="#FFFFFF" sketch:type="MSShapeGroup"></path>
23
+ <path d="M493.745834,194.15 L490.554167,213.916667 C483.604167,210.420834 478.554167,208.995834 473.145834,208.995834 C458.595834,208.995834 448.395834,223.054167 448.395834,243.104167 C448.395834,256.925001 455.254167,265.283334 466.579167,265.283334 C471.379167,265.283334 476.675001,263.791667 483.133334,260.608334 L479.712501,281.358334 C472.529167,283.316668 467.895834,284.029168 462.4875,284.029168 C441.5125,284.029168 428.4375,268.945834 428.4375,244.720834 C428.4375,212.170834 446.495834,189.420833 472.325001,189.420833 C480.833334,189.420833 490.887501,193.029167 493.745834,194.15" id="Fill-14" fill="#FFFFFF" sketch:type="MSShapeGroup"></path>
24
+ <path d="M525.187501,249.758334 C523.145834,249.520834 522.245834,249.458334 520.841668,249.458334 C509.800001,249.458334 504.208334,253.245834 504.208334,260.725001 C504.208334,265.329167 506.937501,268.270834 511.191668,268.270834 C519.129168,268.270834 524.854168,260.712501 525.187501,249.758334 L525.187501,249.758334 L525.187501,249.758334 Z M539.366668,282.741668 L523.216668,282.741668 L523.587501,275.079167 C518.662501,281.133334 512.087501,284.029168 503.166667,284.029168 C492.604167,284.029168 485.362501,275.779167 485.362501,263.800001 C485.362501,245.766667 497.958334,235.258334 519.575001,235.258334 C521.787501,235.258334 524.616668,235.458334 527.516668,235.829167 C528.116668,233.3875 528.279168,232.341667 528.279168,231.020834 C528.279168,226.1125 524.887501,224.291667 515.783334,224.291667 C506.250001,224.183334 498.387501,226.5625 495.154167,227.6125 C495.358334,226.3875 497.858334,210.975 497.858334,210.975 C507.566667,208.116667 513.975001,207.045834 521.175001,207.045834 C537.916668,207.045834 546.779168,214.5625 546.758334,228.75 C546.791668,232.570834 546.162501,237.2625 545.179168,243.425001 C543.495834,254.150001 539.854168,277.150001 539.366668,282.741668 L539.366668,282.741668 L539.366668,282.741668 Z" id="Fill-15" fill="#FFFFFF" sketch:type="MSShapeGroup"></path>
25
+ <path d="M318.974999,281.620834 C313.637499,283.300001 309.479166,284.029168 304.974999,284.029168 C295.012499,284.029168 289.574999,278.304167 289.574999,267.762501 C289.437499,264.483334 291.012499,255.883334 292.249999,248.025001 C293.370832,241.100001 300.695832,197.491667 300.695832,197.491667 L320.062499,197.491667 L317.804166,208.704167 L327.745833,208.704167 L325.099999,226.491667 L315.124999,226.491667 C312.874999,240.583334 309.662499,258.112501 309.629166,260.441667 C309.629166,264.270834 311.670833,265.925001 316.299999,265.925001 C318.520833,265.925001 320.237499,265.708334 321.554166,265.233334 L318.974999,281.620834" id="Fill-16" fill="#FFFFFF" sketch:type="MSShapeGroup"></path>
26
+ <path d="M378.366666,281.029167 C371.716666,283.062501 365.2875,284.041668 358.4875,284.029168 C336.804166,284.008334 325.499999,272.683334 325.499999,250.995834 C325.499999,225.675 339.879166,207.045834 359.4,207.045834 C375.370833,207.045834 385.570833,217.475 385.570833,233.845834 C385.570833,239.279167 384.870833,244.579167 383.1875,252.058334 L344.6125,252.058334 C343.308333,262.800001 350.183333,267.279167 361.45,267.279167 C368.379166,267.279167 374.6375,265.845834 381.5875,262.604167 L378.366666,281.029167 L378.366666,281.029167 Z M367.475,237.116667 C367.591666,235.579167 369.533333,223.9 358.4625,223.9 C352.295833,223.9 347.883333,228.616667 346.0875,237.116667 L367.475,237.116667 L367.475,237.116667 Z" id="Fill-17" fill="#FFFFFF" sketch:type="MSShapeGroup"></path>
27
+ <path d="M244.054165,232.1125 C244.054165,241.479167 248.595832,247.929167 258.895832,252.787501 C266.787499,256.495834 268.008332,257.600001 268.008332,260.958334 C268.008332,265.575001 264.524999,267.658334 256.820832,267.658334 C251.004165,267.658334 245.595832,266.750001 239.354165,264.737501 C239.354165,264.737501 236.799999,281.058334 236.683332,281.837501 C241.104165,282.804168 245.058332,283.687501 256.958332,284.029168 C277.524999,284.029168 287.016666,276.200001 287.016666,259.283334 C287.016666,249.104167 283.045832,243.133334 273.279166,238.645834 C265.112499,234.8875 264.166666,234.0625 264.166666,230.6 C264.166666,226.6 267.412499,224.541667 273.708332,224.541667 C277.529166,224.541667 282.754166,224.9625 287.712499,225.666667 L290.483332,208.4875 C285.441666,207.6875 277.791666,207.045834 273.337499,207.045834 C251.533332,207.045834 243.991665,218.425 244.054165,232.1125" id="Fill-18" fill="#FFFFFF" sketch:type="MSShapeGroup"></path>
28
+ <path d="M642.508335,282.741668 L624.070835,282.741668 L624.987502,275.850001 C619.641668,281.566668 614.162502,284.029168 607.020835,284.029168 C592.854168,284.029168 583.491668,271.816667 583.491668,253.304167 C583.491668,228.675 598.012502,207.9125 615.200002,207.9125 C622.758335,207.9125 628.479168,211 633.804168,218.008334 L638.129169,191.7 L657.350002,191.7 L642.508335,282.741668 L642.508335,282.741668 Z M613.762502,265.633334 C622.837502,265.633334 629.212502,255.350001 629.212502,240.679167 C629.212502,231.275 625.583335,226.170834 618.887502,226.170834 C610.050002,226.170834 603.770835,236.4875 603.770835,251.045834 C603.770835,260.733334 607.129168,265.633334 613.762502,265.633334 L613.762502,265.633334 L613.762502,265.633334 Z" id="Fill-19" fill="#FFFFFF" sketch:type="MSShapeGroup"></path>
29
+ <path d="M556.920835,208.704167 C554.479168,231.620834 550.145834,254.833334 546.758334,277.766667 L545.866668,282.741668 L565.358335,282.741668 C572.329168,237.466667 574.016668,228.625 584.945835,229.733334 C586.687501,220.466667 589.929168,212.35 592.345835,208.254167 C584.183335,206.554167 579.625001,211.166667 573.658335,219.929167 C574.129168,216.141667 574.991668,212.4625 574.820835,208.704167 L556.920835,208.704167" id="Fill-20" fill="#FFFFFF" sketch:type="MSShapeGroup"></path>
30
+ <path d="M396.5,208.704167 C394.054167,231.620834 389.720833,254.833334 386.333333,277.766667 L385.445833,282.741668 L404.945833,282.741668 C411.908333,237.466667 413.591667,228.625 424.516667,229.733334 C426.266667,220.466667 429.508334,212.35 431.916667,208.254167 C423.7625,206.554167 419.2,211.166667 413.2375,219.929167 C413.708333,216.141667 414.5625,212.4625 414.4,208.704167 L396.5,208.704167" id="Fill-21" fill="#FFFFFF" sketch:type="MSShapeGroup"></path>
31
+ <path d="M651.066669,276.945834 C651.066669,273.733334 653.662502,271.145834 656.862502,271.145834 C660.066669,271.145834 662.658335,273.733334 662.658335,276.945834 C662.658335,280.141667 660.066669,282.741668 656.862502,282.741668 C653.662502,282.741668 651.066669,280.141667 651.066669,276.945834 L651.066669,276.945834 L651.066669,276.945834 Z M656.862502,281.350001 C659.300002,281.350001 661.266669,279.375001 661.266669,276.945834 C661.266669,274.512501 659.300002,272.537501 656.862502,272.537501 C654.429169,272.537501 652.454169,274.512501 652.454169,276.945834 C652.454169,279.375001 654.429169,281.350001 656.862502,281.350001 L656.862502,281.350001 L656.862502,281.350001 Z M656.079169,279.479167 L654.891669,279.479167 L654.891669,274.395834 L657.045835,274.395834 C657.491669,274.395834 657.954169,274.404167 658.341669,274.650001 C658.758335,274.933334 658.995835,275.416667 658.995835,275.925001 C658.995835,276.500001 658.658335,277.037501 658.108335,277.241667 L659.050002,279.479167 L657.729169,279.479167 L656.950002,277.470834 L656.079169,277.470834 L656.079169,279.479167 L656.079169,279.479167 Z M656.079169,276.600001 L656.733335,276.600001 C656.979169,276.600001 657.245835,276.616667 657.462502,276.500001 C657.658335,276.375001 657.758335,276.137501 657.758335,275.912501 C657.758335,275.725001 657.641669,275.500001 657.470835,275.387501 C657.266669,275.270834 656.929169,275.304167 656.708335,275.304167 L656.079169,275.304167 L656.079169,276.600001 L656.079169,276.600001 Z" id="Fill-22" fill="#FFFFFF" sketch:type="MSShapeGroup"></path>
32
+ </g>
33
+ </g>
34
+ </svg>
img/credit-cards/paypal.svg ADDED
@@ -0,0 +1,52 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?xml version="1.0" encoding="utf-8"?>
2
+ <!-- Generator: Adobe Illustrator 16.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
3
+ <!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
4
+ <svg version="1.1" id="Layer_1" xmlns:sketch="http://www.bohemiancoding.com/sketch/ns"
5
+ xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" width="780px" height="501px"
6
+ viewBox="0 0 780 501" enable-background="new 0 0 780 501" xml:space="preserve">
7
+ <title>amex-outline</title>
8
+ <desc>Created with Sketch.</desc>
9
+ <path fill="#FFFFFF" d="M725,0H55C24.673,0,0,24.673,0,55v391c0,30.327,24.673,55,55,55h670c30.325,0,55-24.673,55-55V55
10
+ C780,24.673,755.325,0,725,0z"/>
11
+ <path fill="#003087" d="M168.379,169.853c-8.399-5.774-19.359-8.668-32.88-8.668H83.153c-4.145,0-6.435,2.073-6.87,6.214
12
+ L55.018,300.883c-0.221,1.311,0.107,2.51,0.981,3.6c0.869,1.092,1.962,1.635,3.271,1.635h24.864c4.361,0,6.758-2.068,7.198-6.215
13
+ l5.888-35.986c0.215-1.744,0.982-3.162,2.291-4.254c1.308-1.09,2.944-1.803,4.907-2.13c1.963-0.324,3.814-0.487,5.562-0.487
14
+ c1.743,0,3.814,0.11,6.217,0.327c2.397,0.218,3.925,0.324,4.58,0.324c18.756,0,33.478-5.285,44.167-15.866
15
+ c10.684-10.577,16.032-25.244,16.032-44.004C180.976,184.96,176.774,175.636,168.379,169.853z M141.389,209.933
16
+ c-1.094,7.635-3.926,12.649-8.506,15.049c-4.581,2.403-11.124,3.597-19.629,3.597l-10.797,0.328l5.563-35.007
17
+ c0.434-2.397,1.851-3.597,4.252-3.597h6.218c8.72,0,15.049,1.257,18.975,3.761C141.389,196.574,142.698,201.866,141.389,209.933z"/>
18
+ <path fill="#009CDE" d="M720.794,161.185h-24.208c-2.405,0-3.821,1.2-4.253,3.599l-21.267,136.099l-0.328,0.654
19
+ c0,1.096,0.437,2.127,1.311,3.109c0.868,0.98,1.963,1.471,3.27,1.471h21.595c4.138,0,6.429-2.068,6.871-6.215l21.265-133.812v-0.325
20
+ C725.049,162.712,723.627,161.185,720.794,161.185z"/>
21
+ <path fill="#003087" d="M428.31,213.857c0-1.088-0.439-2.126-1.306-3.106c-0.875-0.981-1.858-1.474-2.945-1.474h-25.192
22
+ c-2.404,0-4.366,1.096-5.889,3.271l-34.679,51.04l-14.394-49.075c-1.095-3.488-3.493-5.236-7.198-5.236h-24.54
23
+ c-1.093,0-2.075,0.492-2.942,1.474c-0.875,0.98-1.309,2.019-1.309,3.106c0,0.44,2.127,6.871,6.379,19.303
24
+ c4.252,12.434,8.833,25.848,13.741,40.245c4.908,14.393,7.468,22.031,7.688,22.898c-17.886,24.43-26.827,37.517-26.827,39.259
25
+ c0,2.838,1.417,4.254,4.253,4.254h25.192c2.399,0,4.361-1.088,5.889-3.27l83.427-120.399
26
+ C428.092,215.713,428.31,214.953,428.31,213.857z"/>
27
+ <path fill="#009CDE" d="M662.887,209.277h-24.866c-3.055,0-4.904,3.599-5.558,10.797c-5.677-8.72-16.031-13.088-31.083-13.088
28
+ c-15.704,0-29.066,5.89-40.077,17.668c-11.016,11.779-16.521,25.631-16.521,41.551c0,12.871,3.761,23.121,11.285,30.752
29
+ c7.525,7.639,17.612,11.451,30.266,11.451c6.323,0,12.757-1.311,19.3-3.926c6.544-2.617,11.665-6.105,15.379-10.469
30
+ c0,0.219-0.222,1.199-0.655,2.943c-0.44,1.748-0.655,3.059-0.655,3.926c0,3.494,1.414,5.234,4.254,5.234h22.576
31
+ c4.138,0,6.541-2.068,7.194-6.215l13.415-85.389c0.215-1.309-0.112-2.507-0.982-3.599
32
+ C665.284,209.824,664.196,209.277,662.887,209.277z M620.193,273.729c-5.562,5.453-12.268,8.178-20.12,8.178
33
+ c-6.328,0-11.449-1.742-15.377-5.234c-3.927-3.484-5.89-8.283-5.89-14.395c0-8.065,2.726-14.885,8.18-20.447
34
+ c5.447-5.562,12.214-8.343,20.285-8.343c6.101,0,11.173,1.8,15.212,5.398c4.032,3.599,6.054,8.563,6.054,14.888
35
+ C628.536,261.625,625.754,268.279,620.193,273.729z"/>
36
+ <path fill="#003087" d="M291.23,209.277h-24.864c-3.058,0-4.908,3.599-5.563,10.797c-5.889-8.72-16.25-13.088-31.081-13.088
37
+ c-15.704,0-29.065,5.89-40.078,17.668c-11.016,11.779-16.521,25.631-16.521,41.551c0,12.871,3.763,23.121,11.288,30.752
38
+ c7.525,7.639,17.61,11.451,30.262,11.451c6.104,0,12.433-1.311,18.975-3.926c6.543-2.617,11.778-6.105,15.704-10.469
39
+ c-0.875,2.617-1.309,4.908-1.309,6.869c0,3.494,1.417,5.234,4.253,5.234h22.574c4.141,0,6.543-2.068,7.198-6.215l13.413-85.389
40
+ c0.215-1.309-0.112-2.507-0.981-3.599C293.627,209.824,292.538,209.277,291.23,209.277z M248.535,273.891
41
+ c-5.563,5.35-12.382,8.016-20.447,8.016c-6.329,0-11.4-1.742-15.214-5.234c-3.819-3.484-5.726-8.283-5.726-14.395
42
+ c0-8.065,2.725-14.885,8.18-20.447c5.449-5.562,12.211-8.343,20.284-8.343c6.104,0,11.175,1.8,15.214,5.398
43
+ c4.032,3.599,6.052,8.563,6.052,14.888C256.878,261.844,254.097,268.553,248.535,273.891z"/>
44
+ <path fill="#009CDE" d="M540.036,169.853c-8.398-5.774-19.356-8.668-32.879-8.668h-52.019c-4.365,0-6.765,2.073-7.198,6.214
45
+ l-21.265,133.483c-0.221,1.311,0.106,2.51,0.981,3.6c0.866,1.092,1.962,1.635,3.271,1.635h26.826c2.617,0,4.361-1.416,5.235-4.252
46
+ l5.89-37.949c0.216-1.744,0.98-3.162,2.29-4.254c1.309-1.09,2.943-1.803,4.908-2.13c1.962-0.324,3.813-0.487,5.562-0.487
47
+ c1.743,0,3.814,0.11,6.214,0.327c2.399,0.218,3.93,0.324,4.58,0.324c18.759,0,33.479-5.285,44.168-15.866
48
+ c10.687-10.577,16.031-25.244,16.031-44.004C552.632,184.96,548.431,175.636,540.036,169.853z M506.502,223.673
49
+ c-4.799,3.271-11.997,4.906-21.592,4.906l-10.47,0.328l5.563-35.007c0.432-2.397,1.849-3.597,4.252-3.597h5.887
50
+ c4.797,0,8.614,0.218,11.454,0.653c2.831,0.44,5.561,1.799,8.178,4.089c2.619,2.291,3.926,5.618,3.926,9.98
51
+ C513.7,214.185,511.298,220.4,506.502,223.673z"/>
52
+ </svg>
img/credit-cards/unionpay.svg ADDED
@@ -0,0 +1,13 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <svg xmlns="http://www.w3.org/2000/svg" width="750" height="471">
2
+ <g fill="none" fill-rule="evenodd">
3
+ <rect width="750" height="471" fill="#FFF" rx="40"/>
4
+ <path fill="#D10429" d="M201.809581,55 L344.203266,55 C364.072152,55 376.490206,71.4063861 371.833436,91.4702467 L305.500331,378.94775 C300.843561,399.011611 280.871191,415.417997 261.002305,415.417997 L118.60862,415.417997 C98.7397339,415.417997 86.32168,399.011611 90.9784502,378.94775 L157.311555,91.4702467 C161.968325,71.3018868 181.837211,55 201.706097,55 L201.809581,55 Z"/>
5
+ <path fill="#022E64" d="M331.750074,55 L495.564902,55 C515.433788,55 506.430699,71.4063861 501.773929,91.4702467 L435.440824,378.94775 C430.784054,399.011611 432.232827,415.417997 412.363941,415.417997 L248.549113,415.417997 C228.576743,415.417997 216.262173,399.011611 221.022427,378.94775 L287.355531,91.4702467 C292.012302,71.3018868 311.881188,55 331.853558,55 L331.750074,55 Z"/>
6
+ <path fill="#076F74" d="M489.814981,55 L632.208666,55 C652.077552,55 664.495606,71.4063861 659.838836,91.4702467 L593.505731,378.94775 C588.848961,399.011611 568.876591,415.417997 549.007705,415.417997 L406.61402,415.417997 C386.64165,415.417997 374.32708,399.011611 378.98385,378.94775 L445.316955,91.4702467 C449.973725,71.3018868 469.842611,55 489.711498,55 L489.814981,55 Z"/>
7
+ <path fill="#FEFEFE" d="M465.904754,326.014514 L479.357645,326.014514 L483.186545,312.952104 L469.837137,312.952104 L465.904754,326.014514 L465.904754,326.014514 Z M476.667067,290.066763 L476.667067,290.066763 L472.010297,305.532656 C472.010297,305.532656 477.081002,302.920174 479.875064,302.08418 C482.669126,301.457184 486.808478,300.934688 486.808478,300.934688 L490.016475,290.171263 L476.563583,290.171263 L476.667067,290.066763 Z M483.393513,267.912917 L483.393513,267.912917 L478.94371,282.751814 C478.94371,282.751814 483.910932,280.45283 486.704994,279.721335 C489.499056,278.98984 493.638407,278.780842 493.638407,278.780842 L496.846405,268.017417 L483.496997,268.017417 L483.393513,267.912917 Z M513.093359,267.912917 L513.093359,267.912917 L495.708083,325.910015 L500.364853,325.910015 L496.742921,337.927431 L492.086151,337.927431 L490.947829,341.584906 L474.390424,341.584906 L475.528745,337.927431 L442,337.927431 L445.311481,326.850508 L448.726446,326.850508 L466.318689,267.912917 L469.837137,256 L486.704994,256 L484.94577,261.956459 C484.94577,261.956459 489.395572,258.716981 493.741891,257.567489 C497.984726,256.417997 522.406899,256 522.406899,256 L518.784967,267.808418 L512.989875,267.808418 L513.093359,267.912917 Z"/>
8
+ <path fill="#FEFEFE" d="M520 256L538.006178 256 538.213146 262.792453C538.109662 263.941945 539.041016 264.464441 541.214175 264.464441L544.836108 264.464441 541.524627 275.645864 531.797151 275.645864C523.414965 276.272859 520.206968 272.615385 520.413935 268.539913L520.103484 256.104499 520 256zM522.216235 309.20029L505.037927 309.20029 507.935473 299.272859 527.597391 299.272859 530.391454 290.181422 511.039986 290.181422 514.351467 279 568.163034 279 564.851553 290.181422 546.741891 290.181422 543.947829 299.272859 562.057491 299.272859 559.056461 309.20029 539.498026 309.20029 535.979578 313.380261 543.947829 313.380261 545.914021 325.920174C546.120989 327.174165 546.120989 328.01016 546.534924 328.532656 546.948859 328.950653 549.328986 329.159652 550.674275 329.159652L553.054402 329.159652 549.328986 341.386067 543.223443 341.386067C542.292089 341.386067 540.843316 341.281567 538.877124 341.281567 537.014416 341.072569 535.77261 340.027576 534.530805 339.400581 533.392483 338.878084 531.736743 337.519594 531.322808 335.11611L529.4601 322.576197 520.560494 334.907112C517.766432 338.773585 513.937532 341.804064 507.418054 341.804064L495 341.804064 498.311481 330.936139 503.071735 330.936139C504.417024 330.936139 505.65883 330.413643 506.590184 329.891147 507.521538 329.473149 508.349408 329.055152 509.177278 327.696662L522.216235 309.20029 522.216235 309.20029zM334.31354 282L379.742921 282 376.43144 292.972424 358.321778 292.972424 355.527716 302.272859 374.154797 302.272859 370.739832 313.558781 352.216235 313.558781 347.662948 328.711176C347.145529 330.383164 352.112751 330.592163 353.871975 330.592163L363.185516 329.338171 359.4601 341.878084 338.556375 341.878084C336.900635 341.878084 335.65883 341.669086 333.796122 341.251089 332.036897 340.833091 331.209027 339.997097 330.48464 338.847605 329.760254 337.593614 328.518449 336.65312 329.346319 333.936139L335.348378 313.872279 325 313.872279 328.414965 302.377358 338.763343 302.377358 341.557405 293.076923 331.209027 293.076923 334.520508 282.104499 334.31354 282zM365.700875 262.165457L384.327956 262.165457 380.912991 273.555878 355.455981 273.555878 352.661919 275.959361C351.420113 277.108853 351.109662 276.690856 349.557405 277.526851 348.108632 278.258345 345.107603 279.721335 341.175219 279.721335L333 279.721335 336.311481 268.748911 338.795092 268.748911C340.864767 268.748911 342.31354 268.539913 343.037927 268.121916 343.865797 267.599419 344.797151 266.449927 345.728505 264.56894L350.385275 256 368.908872 256 365.700875 262.269956 365.700875 262.165457zM400.808726 280.975327C400.808726 280.975327 405.879431 276.272859 414.572069 274.809869 416.538261 274.391872 428.956314 274.600871 428.956314 274.600871L430.819023 268.330914 404.637626 268.330914 400.808726 281.079826 400.808726 280.975327zM425.437866 285.782293L425.437866 285.782293 399.463436 285.782293 397.91118 291.111756 420.470644 291.111756C423.161223 290.798258 423.678642 291.216255 423.885609 291.007257L425.54135 285.782293 425.437866 285.782293zM391.702153 256.104499L391.702153 256.104499 407.535171 256.104499 405.258528 264.150943C405.258528 264.150943 410.22575 260.075472 413.744198 258.612482 417.262647 257.358491 425.127414 256.104499 425.127414 256.104499L450.791393 256 441.995271 285.468795C440.546498 290.484761 438.787274 293.724238 437.752436 295.291727 436.821082 296.754717 435.68276 298.113208 433.406117 299.367199 431.232958 300.516691 429.266766 301.248186 427.404058 301.352685 425.748317 301.457184 423.057739 301.561684 419.53929 301.561684L394.806666 301.561684 387.873253 324.865022C387.25235 327.164006 386.941899 328.313498 387.355834 328.940493 387.666285 329.46299 388.597639 330.089985 389.735961 330.089985L400.601758 329.044993 396.876342 341.793904 384.665256 341.793904C380.732872 341.793904 377.93881 341.689405 375.972618 341.584906 374.10991 341.375907 372.143718 341.584906 370.798429 340.539913 369.660107 339.49492 367.900883 338.13643 368.004367 336.777939 368.10785 335.523948 368.625269 333.433962 369.45314 330.507983L391.702153 256.104499 391.702153 256.104499z"/>
9
+ <path fill="#FEFEFE" d="M437.840227 303L436.391454 310.105951C435.770551 312.300435 435.253132 313.972424 433.597391 315.435414 431.838167 316.898403 429.871975 318.465893 425.111721 318.465893L416.3156 318.88389 416.212116 326.825835C416.108632 329.020319 416.729535 328.811321 417.039986 329.229318 417.453921 329.647315 417.764373 329.751814 418.178308 329.960813L420.97237 329.751814 429.354556 329.333817 425.836108 341.037736 416.212116 341.037736C409.48567 341.037736 404.414965 340.828737 402.862708 339.574746 401.206968 338.529753 401 337.275762 401 334.976778L401.620903 303.835994 417.039986 303.835994 416.833019 310.21045 420.558435 310.21045C421.80024 310.21045 422.731594 310.105951 423.249013 309.792453 423.766432 309.478955 424.076883 308.956459 424.283851 308.224964L425.836108 303.208999 437.94371 303.208999 437.840227 303zM218.470396 147C217.952978 149.507983 208.018534 195.592163 208.018534 195.592163 205.845375 204.892598 204.293118 211.580552 199.118929 215.865022 196.117899 218.373004 192.599451 219.522496 188.563583 219.522496 182.044105 219.522496 178.318689 216.283019 177.697786 210.117562L177.594302 208.027576C177.594302 208.027576 179.560494 195.592163 179.560494 195.487663 179.560494 195.487663 189.908872 153.478955 191.771581 147.940493 191.875064 147.626996 191.875064 147.417997 191.875064 147.313498 171.695727 147.522496 168.073794 147.313498 167.866827 147 167.763343 147.417997 167.245924 150.030479 167.245924 150.030479L156.690578 197.36865 155.759224 201.339623 154 214.506531C154 218.373004 154.724386 221.612482 156.276643 224.224964 161.140381 232.793904 174.903724 234.047896 182.665008 234.047896 192.702935 234.047896 202.119959 231.853411 208.43247 227.986938 219.505234 221.403483 222.40278 211.058055 224.886391 201.966618L226.128196 197.264151C226.128196 197.264151 236.787026 153.687954 238.649734 148.044993 238.753218 147.731495 238.753218 147.522496 238.856702 147.417997 224.162004 147.522496 219.919169 147.417997 218.470396 147.104499L218.470396 147zM277.499056 233.622642C270.358675 233.518142 267.771581 233.518142 259.389394 233.936139L259.078943 233.309144C259.803329 230.069666 260.6312 226.934688 261.252102 223.69521L262.28694 219.306241C263.839197 212.513788 265.28797 204.467344 265.494937 202.063861 265.701905 200.600871 266.11584 196.943396 261.976489 196.943396 260.217264 196.943396 258.45804 197.77939 256.595332 198.615385 255.560494 202.272859 253.594302 212.513788 252.559465 217.111756 250.489789 226.934688 250.386305 228.08418 249.454951 232.891147L248.834048 233.518142C241.4867 233.413643 238.899605 233.413643 230.413935 233.83164L230 233.100145C231.448773 227.248186 232.794062 221.396226 234.139351 215.544267 237.6578 199.764877 238.589154 193.703919 239.520508 185.657475L240.244894 185.239478C248.523597 184.089985 250.489789 183.776488 259.492878 182L260.217264 182.835994 258.871975 187.851959C260.424232 186.911466 261.873005 185.970972 263.425262 185.239478 267.668097 183.149492 272.324867 182.522496 274.911962 182.522496 278.844345 182.522496 283.190664 183.671988 284.949888 188.269956 286.605629 192.345428 285.570791 197.361393 283.294148 207.288824L282.155826 212.30479C279.879183 223.381713 279.465248 225.367199 278.223443 232.891147L277.395572 233.518142 277.499056 233.622642zM306.558435 233.650218C302.212116 233.650218 299.418054 233.545718 296.727476 233.650218 294.036897 233.650218 291.449803 233.859216 287.413935 233.963716L287.206968 233.650218 287 233.232221C288.138322 229.05225 288.655741 227.58926 289.276643 226.12627 289.794062 224.66328 290.311481 223.20029 291.346319 218.91582 292.588124 213.377358 293.415995 209.510885 293.933413 206.062409 294.554316 202.822932 294.864767 200.001451 295.278703 196.761974L295.589154 196.552975 295.899605 196.239478C300.245924 195.612482 302.936502 195.194485 305.730565 194.776488 308.524627 194.358491 311.422173 193.835994 315.871975 193L316.078943 193.417997 316.182427 193.835994C315.354556 197.28447 314.526686 200.732946 313.698816 204.181422 312.870946 207.629898 312.043075 211.078374 311.318689 214.526851 309.766432 221.8418 309.042046 224.558781 308.731594 226.544267 308.317659 228.425254 308.214175 229.365747 307.593273 233.127721L307.179338 233.441219 306.765402 233.754717 306.558435 233.650218zM352.499319 207.975327C352.188868 209.856313 350.533127 216.857765 348.359968 219.783745 346.807711 221.978229 345.048487 223.33672 342.978811 223.33672 342.357909 223.33672 338.83946 223.33672 338.735976 218.007257 338.735976 215.394775 339.253395 212.677794 339.874298 209.751814 341.737006 201.287373 344.013649 194.285922 349.705257 194.285922 354.15506 194.285922 354.465511 199.510885 352.499319 207.975327L352.499319 207.975327zM371.229884 208.811321L371.229884 208.811321C373.713495 197.734398 371.747303 192.509434 369.367176 189.374456 365.64176 184.567489 359.018798 183 352.188868 183 348.049517 183 338.322041 183.417997 330.664241 190.523948 325.179601 195.644412 322.592506 202.645864 321.143733 209.333817 319.591476 216.12627 317.832252 228.352685 329.008501 232.950653 332.423466 234.413643 337.390687 234.83164 340.598684 234.83164 348.773903 234.83164 357.156089 232.532656 363.4686 225.844702 368.332338 220.41074 370.505497 212.259797 371.333368 208.811321L371.229884 208.811321zM545.661919 234.891147C536.969281 234.786647 534.48567 234.786647 526.517419 235.204644L526 234.577649C528.173159 226.322206 530.346319 217.962264 532.312511 209.602322 534.796122 198.734398 535.417024 194.13643 536.244894 187.761974L536.865797 187.239478C545.454951 185.985486 547.835078 185.671988 556.838167 184L557.045135 184.731495C555.389394 191.628447 553.837137 198.4209 552.181397 205.213353 548.869916 219.529753 547.731594 226.844702 546.489789 234.36865L545.661919 234.995646 545.661919 234.891147z"/>
10
+ <path fill="#FEFEFE" d="M533.159909 209.373777C532.745974 211.150265 531.090233 218.256216 528.917074 221.182195 527.468301 223.272181 523.949852 224.630672 521.983661 224.630672 521.362758 224.630672 517.947793 224.630672 517.740826 219.405708 517.740826 216.793226 518.258244 214.076245 518.879147 211.150265 520.741855 202.894822 523.018498 195.893371 528.710106 195.893371 533.159909 195.893371 535.126101 201.013836 533.159909 209.478277L533.159909 209.373777zM550.234733 210.209772L550.234733 210.209772C552.718344 199.132849 542.576933 209.269278 541.024677 205.611804 538.541066 199.864344 540.093322 188.369423 530.158879 184.50295 526.329979 182.935461 517.32689 184.920947 509.66909 192.026898 504.287934 197.042863 501.597355 204.044315 500.148582 210.732268 498.596326 217.420222 496.837101 229.751136 507.909866 234.035606 511.428315 235.603095 514.636312 236.021092 517.844309 235.812094 529.020558 235.185098 537.506228 218.151717 543.818739 211.463763 548.682476 206.1343 549.510347 213.449249 550.234733 210.209772L550.234733 210.209772zM420.292089 233.622642C413.151708 233.518142 410.668097 233.518142 402.28591 233.936139L401.975459 233.309144C402.699846 230.069666 403.527716 226.934688 404.252102 223.69521L405.183456 219.306241C406.735713 212.513788 408.28797 204.467344 408.391454 202.063861 408.598421 200.600871 409.012356 196.943396 404.976489 196.943396 403.217264 196.943396 401.354556 197.77939 399.595332 198.615385 398.663978 202.272859 396.594302 212.513788 395.559465 217.111756 393.593273 226.934688 393.386305 228.08418 392.454951 232.891147L391.834048 233.518142C384.4867 233.413643 381.899605 233.413643 373.413935 233.83164L373 233.100145C374.448773 227.248186 375.794062 221.396226 377.139351 215.544267 380.6578 199.764877 381.48567 193.703919 382.520508 185.657475L383.141411 185.239478C391.420113 184.089985 393.489789 183.776488 402.389394 182L403.113781 182.835994 401.871975 187.851959C403.320748 186.911466 404.873005 185.970972 406.321778 185.239478 410.564613 183.149492 415.221383 182.522496 417.808478 182.522496 421.740862 182.522496 425.983697 183.671988 427.846405 188.269956 429.502145 192.345428 428.363824 197.361393 426.08718 207.288824L424.948859 212.30479C422.568732 223.381713 422.25828 225.367199 421.016475 232.891147L420.188605 233.518142 420.292089 233.622642zM482.293118 147.104499L476.291059 147.208999C460.768492 147.417997 454.559465 147.313498 452.075854 147 451.868886 148.149492 451.454951 150.134978 451.454951 150.134978 451.454951 150.134978 445.866827 176.050798 445.866827 176.155298 445.866827 176.155298 432.620903 231.330914 432 233.943396 445.556375 233.734398 451.041016 233.734398 453.421143 234.047896 453.938562 231.435414 457.043075 216.07402 457.146559 216.07402 457.146559 216.07402 459.837137 204.788099 459.940621 204.370102 459.940621 204.370102 460.768492 203.22061 461.596362 202.698113L462.838167 202.698113C474.531835 202.698113 487.674275 202.698113 498.022653 195.069666 505.05955 189.844702 509.819804 182.007257 511.992964 172.602322 512.510383 170.303338 512.924318 167.586357 512.924318 164.764877 512.924318 161.107402 512.199931 157.554427 510.130256 154.732946 504.852583 147.313498 494.400721 147.208999 482.293118 147.104499L482.293118 147.104499zM490.054402 174.169811L490.054402 174.169811C488.812597 179.917271 485.08718 184.828737 480.326926 187.127721 476.394543 189.113208 471.634289 189.322206 466.667067 189.322206L463.45907 189.322206 463.666037 188.068215C463.666037 188.068215 469.564613 162.152395 469.564613 162.256894L469.771581 160.898403 469.875064 159.853411 472.255191 160.062409C472.255191 160.062409 484.466278 161.107402 484.673245 161.107402 489.433499 162.988389 491.503175 167.795356 490.054402 174.169811L490.054402 174.169811zM617.261369 182.835994L616.536983 182C607.740862 183.776488 606.085121 184.089985 598.013386 185.239478L597.392483 185.866473C597.392483 185.970972 597.288999 186.075472 597.288999 186.28447L597.288999 186.179971C591.28694 200.287373 591.390424 197.256894 586.526686 208.333817 586.526686 207.811321 586.526686 207.497823 586.423202 206.975327L585.181397 182.940493 584.45701 182.104499C575.14347 183.880987 574.936502 184.194485 566.450832 185.343977L565.82993 185.970972C565.726446 186.28447 565.726446 186.597968 565.726446 186.911466L565.82993 187.015965C566.864767 192.554427 566.6578 191.300435 567.692638 199.973875 568.210057 204.258345 568.830959 208.542816 569.348378 212.722787 570.176248 219.828737 570.693667 223.277213 571.728505 234.040639 565.933413 243.654572 564.588124 247.312046 559 255.776488L559.310451 256.612482C567.692638 256.298984 569.555346 256.298984 575.764373 256.298984L577.109662 254.731495C581.766432 244.595065 617.364853 182.940493 617.364853 182.940493L617.261369 182.835994zM314.543608 189.75837C319.303862 186.414394 319.924765 181.816425 315.888897 179.412942 311.85303 177.009459 304.712649 177.740954 299.952395 181.084931 295.192141 184.324408 294.674722 188.922376 298.71059 191.430359 302.642973 193.729343 309.783354 193.102347 314.543608 189.75837L314.543608 189.75837z"/>
11
+ <path fill="#FEFEFE" d="M575.734683,256.104499 L568.80127,268.121916 C566.628111,272.197388 562.488759,275.332366 556.072765,275.332366 L545,275.123367 L548.207997,264.255443 L550.381157,264.255443 C551.519478,264.255443 552.347349,264.150943 552.968251,263.837446 C553.589154,263.628447 553.899605,263.21045 554.417024,262.583454 L558.556375,256 L575.838167,256 L575.734683,256.104499 Z"/>
12
+ </g>
13
+ </svg>
img/credit-cards/visa.svg ADDED
@@ -0,0 +1,17 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?xml version="1.0" encoding="UTF-8" standalone="no"?>
2
+ <svg width="750px" height="471px" viewBox="0 0 750 471" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:sketch="http://www.bohemiancoding.com/sketch/ns">
3
+ <!-- Generator: Sketch 3.3.1 (12005) - http://www.bohemiancoding.com/sketch -->
4
+ <title>Slice 1</title>
5
+ <desc>Created with Sketch.</desc>
6
+ <defs></defs>
7
+ <g id="Page-1" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd" sketch:type="MSPage">
8
+ <g id="visa" sketch:type="MSLayerGroup">
9
+ <rect id="Rectangle-1" fill="#0E4595" sketch:type="MSShapeGroup" x="0" y="0" width="750" height="471" rx="40"></rect>
10
+ <path d="M278.1975,334.2275 L311.5585,138.4655 L364.9175,138.4655 L331.5335,334.2275 L278.1975,334.2275 L278.1975,334.2275 Z" id="Shape" fill="#FFFFFF" sketch:type="MSShapeGroup"></path>
11
+ <path d="M524.3075,142.6875 C513.7355,138.7215 497.1715,134.4655 476.4845,134.4655 C423.7605,134.4655 386.6205,161.0165 386.3045,199.0695 C386.0075,227.1985 412.8185,242.8905 433.0585,252.2545 C453.8275,261.8495 460.8105,267.9695 460.7115,276.5375 C460.5795,289.6595 444.1255,295.6545 428.7885,295.6545 C407.4315,295.6545 396.0855,292.6875 378.5625,285.3785 L371.6865,282.2665 L364.1975,326.0905 C376.6605,331.5545 399.7065,336.2895 423.6355,336.5345 C479.7245,336.5345 516.1365,310.2875 516.5505,269.6525 C516.7515,247.3835 502.5355,230.4355 471.7515,216.4645 C453.1005,207.4085 441.6785,201.3655 441.7995,192.1955 C441.7995,184.0585 451.4675,175.3575 472.3565,175.3575 C489.8055,175.0865 502.4445,178.8915 512.2925,182.8575 L517.0745,185.1165 L524.3075,142.6875" id="path13" fill="#FFFFFF" sketch:type="MSShapeGroup"></path>
12
+ <path d="M661.6145,138.4655 L620.3835,138.4655 C607.6105,138.4655 598.0525,141.9515 592.4425,154.6995 L513.1975,334.1025 L569.2285,334.1025 C569.2285,334.1025 578.3905,309.9805 580.4625,304.6845 C586.5855,304.6845 641.0165,304.7685 648.7985,304.7685 C650.3945,311.6215 655.2905,334.1025 655.2905,334.1025 L704.8025,334.1025 L661.6145,138.4655 L661.6145,138.4655 Z M596.1975,264.8725 C600.6105,253.5935 617.4565,210.1495 617.4565,210.1495 C617.1415,210.6705 621.8365,198.8155 624.5315,191.4655 L628.1385,208.3435 C628.1385,208.3435 638.3555,255.0725 640.4905,264.8715 L596.1975,264.8715 L596.1975,264.8725 L596.1975,264.8725 Z" id="Path" fill="#FFFFFF" sketch:type="MSShapeGroup"></path>
13
+ <path d="M232.9025,138.4655 L180.6625,271.9605 L175.0965,244.8315 C165.3715,213.5575 135.0715,179.6755 101.1975,162.7125 L148.9645,333.9155 L205.4195,333.8505 L289.4235,138.4655 L232.9025,138.4655" id="path16" fill="#FFFFFF" sketch:type="MSShapeGroup"></path>
14
+ <path d="M131.9195,138.4655 L45.8785,138.4655 L45.1975,142.5385 C112.1365,158.7425 156.4295,197.9015 174.8155,244.9525 L156.1065,154.9925 C152.8765,142.5965 143.5085,138.8975 131.9195,138.4655" id="path18" fill="#F2AE14" sketch:type="MSShapeGroup"></path>
15
+ </g>
16
+ </g>
17
+ </svg>
img/credit-dots.svg ADDED
@@ -0,0 +1,31 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+ <svg width="112px" height="4px" viewBox="0 0 112 4" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
3
+ <!-- Generator: Sketch 43.2 (39069) - http://www.bohemiancoding.com/sketch -->
4
+ <title>credit-numbers</title>
5
+ <desc>Created with Sketch.</desc>
6
+ <defs></defs>
7
+ <g id="wp-translation" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
8
+ <g id="Terms-and-Conditions" transform="translate(-859.000000, -324.000000)" fill="#000000">
9
+ <g id="modal" transform="translate(-1.000000, 5.000000)">
10
+ <g id="payment-method" transform="translate(822.000000, 236.000000)">
11
+ <g id="credit-info" transform="translate(8.000000, 34.000000)">
12
+ <g id="credit-numbers" transform="translate(30.000000, 49.000000)">
13
+ <circle id="Oval-13" cx="2" cy="2" r="2"></circle>
14
+ <circle id="Oval-13" cx="10" cy="2" r="2"></circle>
15
+ <circle id="Oval-13" cx="19" cy="2" r="2"></circle>
16
+ <circle id="Oval-13" cx="28" cy="2" r="2"></circle>
17
+ <circle id="Oval-13" cx="42" cy="2" r="2"></circle>
18
+ <circle id="Oval-13" cx="51" cy="2" r="2"></circle>
19
+ <circle id="Oval-13" cx="60" cy="2" r="2"></circle>
20
+ <circle id="Oval-13" cx="69" cy="2" r="2"></circle>
21
+ <circle id="Oval-13" cx="83" cy="2" r="2"></circle>
22
+ <circle id="Oval-13" cx="92" cy="2" r="2"></circle>
23
+ <circle id="Oval-13" cx="101" cy="2" r="2"></circle>
24
+ <circle id="Oval-13" cx="110" cy="2" r="2"></circle>
25
+ </g>
26
+ </g>
27
+ </g>
28
+ </g>
29
+ </g>
30
+ </g>
31
+ </svg>
img/error.svg ADDED
@@ -0,0 +1,15 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+ <svg width="81px" height="81px" viewBox="0 0 81 81" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
3
+ <!-- Generator: Sketch 43.2 (39069) - http://www.bohemiancoding.com/sketch -->
4
+ <title>ic_error_black_24px (2)</title>
5
+ <desc>Created with Sketch.</desc>
6
+ <defs></defs>
7
+ <g id="wp-translation" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
8
+ <g id="Error-Modal-Screen" transform="translate(-763.000000, -381.000000)">
9
+ <g id="ic_error_black_24px-(2)" transform="translate(756.000000, 374.000000)">
10
+ <polygon id="Shape" points="0 0 95 0 95 95 0 95"></polygon>
11
+ <path d="M47.5,7.91666667 C25.65,7.91666667 7.91666667,25.65 7.91666667,47.5 C7.91666667,69.35 25.65,87.0833333 47.5,87.0833333 C69.35,87.0833333 87.0833333,69.35 87.0833333,47.5 C87.0833333,25.65 69.35,7.91666667 47.5,7.91666667 Z M51.4583333,67.2916667 L43.5416667,67.2916667 L43.5416667,59.375 L51.4583333,59.375 L51.4583333,67.2916667 Z M51.4583333,51.4583333 L43.5416667,51.4583333 L43.5416667,27.7083333 L51.4583333,27.7083333 L51.4583333,51.4583333 Z" id="Shape" fill="#F13B3B" fill-rule="nonzero"></path>
12
+ </g>
13
+ </g>
14
+ </g>
15
+ </svg>
img/human-translation.svg ADDED
@@ -0,0 +1,18 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+ <svg width="14px" height="15px" viewBox="0 0 14 15" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
3
+ <!-- Generator: Sketch 44.1 (41455) - http://www.bohemiancoding.com/sketch -->
4
+ <title>human-translation-svg</title>
5
+ <desc>Created with Sketch.</desc>
6
+ <defs></defs>
7
+ <g id="wp-translation" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
8
+ <g id="Posts-Screen---Step-5--download" transform="translate(-1005.000000, -204.000000)" fill-rule="nonzero" fill="#FF7B12">
9
+ <g id="Body-boxes" transform="translate(224.000000, 155.000000)">
10
+ <g id="post" transform="translate(0.000000, 39.000000)">
11
+ <g id="human-translation-svg" transform="translate(781.000000, 10.000000)">
12
+ <path d="M7,6.34375 C5.01375,6.34375 4.61125,3.33375 4.61125,3.33375 C4.375,1.7675 5.0925,0 6.97375,0 C8.86375,0 9.58125,1.7675 9.345,3.33375 C9.345,3.33375 8.98625,6.34375 7,6.34375 Z M7,8.5925 L9.38,7 C11.47125,7 13.335,9.03875 13.335,10.96375 L13.335,13.1425 C13.335,13.1425 10.14125,14.13125 7,14.13125 C3.80625,14.13125 0.665,13.1425 0.665,13.1425 L0.665,10.96375 C0.665,8.995 2.3625,7.04375 4.57625,7.04375 L7,8.5925 Z" id="Shape"></path>
13
+ </g>
14
+ </g>
15
+ </g>
16
+ </g>
17
+ </g>
18
+ </svg>
img/lingotek-logo-white.png ADDED
Binary file
img/loading.gif ADDED
Binary file
img/loading_mini.gif ADDED
Binary file
img/minimum-help.svg ADDED
@@ -0,0 +1,20 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+ <svg width="13px" height="13px" viewBox="0 0 13 13" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
3
+ <!-- Generator: Sketch 44.1 (41455) - http://www.bohemiancoding.com/sketch -->
4
+ <title>ic_help_outline_black_24px-_1_</title>
5
+ <desc>Created with Sketch.</desc>
6
+ <defs></defs>
7
+ <g id="mini" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
8
+ <g id="mini-one" transform="translate(-508.000000, -319.000000)" fill-rule="nonzero" fill="#95989A">
9
+ <g id="1" transform="translate(-2.000000, -3.000000)">
10
+ <g id="new-idea">
11
+ <g id="new-idea-expanded-final">
12
+ <g id="ic_help_outline_black_24px-_1_" transform="translate(510.000000, 322.000000)">
13
+ <path d="M6.067,10.267 L7.267,10.267 L7.267,9.067 L6.067,9.067 L6.067,10.267 Z M6.667,0.667 C3.3532915,0.667 0.667,3.3532915 0.667,6.667 C0.667,9.9807085 3.3532915,12.667 6.667,12.667 C9.9807085,12.667 12.667,9.9807085 12.667,6.667 C12.667,5.07570106 12.034859,3.54957758 10.9096407,2.42435931 C9.78442242,1.29914104 8.25829894,0.667 6.667,0.667 Z M6.667,11.467 C4.0160332,11.467 1.867,9.3179668 1.867,6.667 C1.867,4.0160332 4.0160332,1.867 6.667,1.867 C9.3179668,1.867 11.467,4.0160332 11.467,6.667 C11.4636942,9.31659628 9.31659628,11.4636942 6.667,11.467 Z M6.667,3.067 C5.3415166,3.067 4.267,4.1415166 4.267,5.467 L5.467,5.467 C5.467,4.8042583 6.0042583,4.267 6.667,4.267 C7.3297417,4.267 7.867,4.8042583 7.867,5.467 C7.867,6.667 6.067,6.517 6.067,8.467 L7.267,8.467 C7.267,7.117 9.067,6.967 9.067,5.467 C9.067,4.83048042 8.81414358,4.22003103 8.36405627,3.76994373 C7.91396897,3.31985642 7.30351958,3.067 6.667,3.067 Z" id="Shape-56"></path>
14
+ </g>
15
+ </g>
16
+ </g>
17
+ </g>
18
+ </g>
19
+ </g>
20
+ </svg>
img/minimum-warning.svg ADDED
@@ -0,0 +1,21 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+ <svg width="22px" height="19px" viewBox="0 0 22 19" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
3
+ <!-- Generator: Sketch 44.1 (41455) - http://www.bohemiancoding.com/sketch -->
4
+ <title>ic_warning_black_24px-_1_</title>
5
+ <desc>Created with Sketch.</desc>
6
+ <defs></defs>
7
+ <g id="mini" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
8
+ <g id="mini-one" transform="translate(-289.000000, -320.000000)">
9
+ <g id="1" transform="translate(-2.000000, -3.000000)">
10
+ <g id="new-idea">
11
+ <g id="new-idea-expanded-final">
12
+ <g id="ic_warning_black_24px-_1_" transform="translate(290.000000, 321.000000)">
13
+ <polygon id="Shape-54" points="0 0 24 0 24 24 0 24"></polygon>
14
+ <path d="M1,21 L23,21 L12,2 L1,21 Z M13,18 L11,18 L11,16 L13,16 L13,18 Z M13,14 L11,14 L11,10 L13,10 L13,14 Z" id="Shape-55" fill="#FF7F00" fill-rule="nonzero"></path>
15
+ </g>
16
+ </g>
17
+ </g>
18
+ </g>
19
+ </g>
20
+ </g>
21
+ </svg>
img/questionmark.svg ADDED
@@ -0,0 +1,14 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+ <svg width="10px" height="19px" viewBox="0 0 10 19" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
3
+ <!-- Generator: Sketch 44.1 (41455) - http://www.bohemiancoding.com/sketch -->
4
+ <title>?</title>
5
+ <desc>Created with Sketch.</desc>
6
+ <defs></defs>
7
+ <g id="wp-translation" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd" font-size="26" font-family="Roboto-Light, Roboto" font-weight="300">
8
+ <g id="Bulk---Scroll-2" transform="translate(-523.000000, -623.000000)" fill="#C8C8C8">
9
+ <text id="?">
10
+ <tspan x="522.292969" y="642">?</tspan>
11
+ </text>
12
+ </g>
13
+ </g>
14
+ </svg>
img/right-arrow.svg ADDED
@@ -0,0 +1,16 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+ <svg width="7px" height="10px" viewBox="0 0 7 10" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
3
+ <!-- Generator: Sketch 43.1 (39012) - http://www.bohemiancoding.com/sketch -->
4
+ <title>Bitmap</title>
5
+ <desc>Created with Sketch.</desc>
6
+ <defs></defs>
7
+ <g id="Page-1" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
8
+ <g id="Bulk---New-User" transform="translate(-799.000000, -428.000000)">
9
+ <g id="modal" transform="translate(-2.000000, 4.000000)">
10
+ <g id="translation-content" transform="translate(353.000000, 385.000000)">
11
+ <image id="Bitmap" x="442" y="35" width="18" height="18" xlink:href="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABgAAAAYCAYAAADgdz34AAAABGdBTUEAA1teXP8meAAAAJpJREFUSA1jYBgFoyFArxCIBVoUQ45lLERoUgWqMUdStwSJTZDJTFAFA8M7oBoQ1gNiGSAWAuJLQEwUIMYCkEFPgJgsS4i1gGxLSLGALEuYQLooAIyE9BJUgGaABZAPS64ngezFaPIYXFIsINlwkG3EWkCW4SALiIkDYaA6koIFZDAMEJOKvgMVg/IAiCYY5jCDR+nREKBeCAAA5k4ZOeNL0CoAAAAASUVORK5CYII="></image>
12
+ </g>
13
+ </g>
14
+ </g>
15
+ </g>
16
+ </svg>
img/translation-logo.png ADDED
Binary file
include/api.php CHANGED
@@ -12,11 +12,15 @@ class Lingotek_API extends Lingotek_HTTP {
12
  protected $base_url;
13
  protected $api_url;
14
  protected $client_id;
 
15
 
16
  const PRODUCTION_URL = "https://myaccount.lingotek.com";
17
  const SANDBOX_URL = "https://cms.lingotek.com";
18
  const CLIENT_ID = "780966c9-f9c8-4691-96e2-c0aaf47f62ff";// Lingotek App ID
19
 
 
 
 
20
  /**
21
  * constructor
22
  *
@@ -30,6 +34,8 @@ class Lingotek_API extends Lingotek_HTTP {
30
  $token_details = get_option('lingotek_token');
31
  $this->headers['Authorization'] = 'bearer ' . $token_details['access_token'];
32
  $this->defaults = get_option('lingotek_defaults');
 
 
33
  }
34
 
35
  public function get_token_details($access_token) {
@@ -229,7 +235,7 @@ class Lingotek_API extends Lingotek_HTTP {
229
 
230
  if (!is_wp_error($response) && 200 == wp_remote_retrieve_response_code($response)) {
231
  $documents = json_decode(wp_remote_retrieve_body($response));
232
- foreach ($documents->entities as $doc) {
233
  $docs[] = $doc;
234
  }
235
  }
@@ -321,6 +327,114 @@ class Lingotek_API extends Lingotek_HTTP {
321
  return empty($translations) ? array() : $translations;
322
  }
323
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
324
  /**
325
  * requests a new translation of a document
326
  *
@@ -374,6 +488,10 @@ class Lingotek_API extends Lingotek_HTTP {
374
  */
375
  public function get_translation($doc_id, $locale, $wp_id = null) {
376
  $locale = Lingotek::map_to_lingotek_locale($locale);
 
 
 
 
377
  $response = $this->get(add_query_arg(array('locale_code' => $locale, 'auto_format' => 'true') , $this->api_url . '/document/' . $doc_id . '/content'));
378
 
379
  if ($wp_id) {
@@ -477,4 +595,16 @@ class Lingotek_API extends Lingotek_HTTP {
477
  $args = array('name' => $name, 'type' => $type, 'content' => $content);
478
  $response = $this->post($this->api_url . '/filter', $args);
479
  }
 
 
 
 
 
 
 
 
 
 
 
 
480
  }
12
  protected $base_url;
13
  protected $api_url;
14
  protected $client_id;
15
+ private $auth_temp;
16
 
17
  const PRODUCTION_URL = "https://myaccount.lingotek.com";
18
  const SANDBOX_URL = "https://cms.lingotek.com";
19
  const CLIENT_ID = "780966c9-f9c8-4691-96e2-c0aaf47f62ff";// Lingotek App ID
20
 
21
+
22
+ private $bridge_url = '';
23
+
24
  /**
25
  * constructor
26
  *
34
  $token_details = get_option('lingotek_token');
35
  $this->headers['Authorization'] = 'bearer ' . $token_details['access_token'];
36
  $this->defaults = get_option('lingotek_defaults');
37
+
38
+ $this->bridge_url = BRIDGE_URL . '/api/v2/transaction/translation/';
39
  }
40
 
41
  public function get_token_details($access_token) {
235
 
236
  if (!is_wp_error($response) && 200 == wp_remote_retrieve_response_code($response)) {
237
  $documents = json_decode(wp_remote_retrieve_body($response));
238
+ foreach ($documents->entities as $doc) {
239
  $docs[] = $doc;
240
  }
241
  }
327
  return empty($translations) ? array() : $translations;
328
  }
329
 
330
+
331
+ public function get_language_mappings()
332
+ {
333
+ $url = 'https://gmc.lingotek.com/v1/locales';
334
+ $response = $this->get($url);
335
+ return json_decode(wp_remote_retrieve_body($response),true);
336
+ }
337
+
338
+ /**
339
+ * Makes an API call to bridge to get the estimated cost for translating a particular document professionally.
340
+ *
341
+ * @param string $lingotek_auth the auth token to make an API call to bridge.
342
+ * @param string $document_id the id of the specific document.
343
+ * @param string $locale the locale of the document being requested.
344
+ */
345
+ public function get_cost_estimate($lingotek_auth, $document_id, $locale) {
346
+ $this->start_bridge_call();
347
+
348
+ $args = array(
349
+ 'document_id' => $document_id,
350
+ 'locale' => $locale
351
+ );
352
+ $response = $this->get($this->bridge_url . 'estimate', $args);
353
+
354
+ $success = 200 === wp_remote_retrieve_response_code($response);
355
+
356
+ $this->end_bridge_call();
357
+ return array('success' => $success, 'data' => $this->get_response_body_from_bridge($response));
358
+ }
359
+
360
+ /**
361
+ * Makes an API call to bridge request translation for a document using the professional workflow.
362
+ *
363
+ * @param string $document_id the id of the specific document.
364
+ * @param string $locale the locale of the document being requested.
365
+ * @param string $workflow_id the id used to process the document.
366
+ */
367
+ public function request_professional_translation($document_id, $locale, $workflow_id) {
368
+ $this->start_bridge_call();
369
+
370
+ $args = array(
371
+ 'document_id' => $document_id,
372
+ 'locale' => $locale,
373
+ 'workflow_id' => $workflow_id,
374
+ );
375
+ $response = $this->post($this->bridge_url . 'request', $args);
376
+ $success = 200 === wp_remote_retrieve_response_code($response);
377
+
378
+ $this->end_bridge_call();
379
+ return array('success' => $success, 'data' => $this->get_response_body_from_bridge($response));
380
+ }
381
+
382
+ /**
383
+ * Makes an API call to bridge request bulk translations for a document using the professional workflow.
384
+ *
385
+ * @param string $document_id the id of the specific document.
386
+ * @param string $locale the locale of the document being requested.
387
+ * @param string $workflow_id the id used to process the document.
388
+ */
389
+ public function request_professional_translation_bulk($workflow_id, $translations, $total_estimate, $summary) {
390
+ $this->start_bridge_call();
391
+
392
+ $args = array(
393
+ 'workflow_id' => $workflow_id,
394
+ 'translations' => $translations,
395
+ 'total_estimate' => $total_estimate,
396
+ 'summary' => $summary
397
+ );
398
+ $response = $this->post($this->bridge_url . 'request/bulk', $args, 60);
399
+ $success = 200 === wp_remote_retrieve_response_code($response);
400
+
401
+ $this->end_bridge_call();
402
+ return array('data' => $this->get_response_body_from_bridge($response));
403
+ }
404
+
405
+
406
+ public function get_lingotek_terms_and_conditions() {
407
+ $this->start_bridge_call();
408
+ $response = $this->get(BRIDGE_URL . '/api/v2/transaction/terms/');
409
+ $success = 200 === wp_remote_retrieve_response_code($response);
410
+ $this->end_bridge_call();
411
+ return array('success' => $success, 'data' => $this->get_response_body_from_bridge($response));
412
+ }
413
+
414
+ /**
415
+ * Makes an API call to bridge to get the payment information about the user.
416
+ */
417
+ public function get_user_payment_information() {
418
+ $this->start_bridge_call();
419
+
420
+ $response = $this->get(BRIDGE_URL . '/api/v2/transaction/payment');
421
+ $success = 200 === wp_remote_retrieve_response_code($response);
422
+
423
+ $this->end_bridge_call();
424
+ return array('success' => $success, 'payment_info' => $this->get_response_body_from_bridge($response));
425
+ }
426
+
427
+ /**
428
+ * Helper function to retrieve the response body from bridge.
429
+ *
430
+ * @param array $response the response from bridge.
431
+ */
432
+ private function get_response_body_from_bridge($response)
433
+ {
434
+ $body = json_decode(wp_remote_retrieve_body($response),true);
435
+ return isset($body) ? $body : wp_remote_retrieve_body($response);
436
+ }
437
+
438
  /**
439
  * requests a new translation of a document
440
  *
488
  */
489
  public function get_translation($doc_id, $locale, $wp_id = null) {
490
  $locale = Lingotek::map_to_lingotek_locale($locale);
491
+ $statuses = $this->get_translations_status($doc_id);
492
+ if (isset($statuses[$locale]) && $statuses[$locale] != 100) {
493
+ return false;
494
+ }
495
  $response = $this->get(add_query_arg(array('locale_code' => $locale, 'auto_format' => 'true') , $this->api_url . '/document/' . $doc_id . '/content'));
496
 
497
  if ($wp_id) {
595
  $args = array('name' => $name, 'type' => $type, 'content' => $content);
596
  $response = $this->post($this->api_url . '/filter', $args);
597
  }
598
+
599
+ private function start_bridge_call() {
600
+ $this->auth_temp = $this->headers['Authorization'];
601
+ unset($this->headers['Authorization']);
602
+ $option = get_option('lingotek_token');
603
+ $this->headers['Authorization-Lingotek'] = $option['access_token'];
604
+ }
605
+
606
+ private function end_bridge_call() {
607
+ unset($this->headers['Authorization-Lingotek']);
608
+ $this->headers['Authorization'] = $this->auth_temp;
609
+ }
610
  }
include/group-post.php CHANGED
@@ -293,11 +293,9 @@ class Lingotek_Group_Post extends Lingotek_Group {
293
  remove_filter('content_filtered_save_pre', 'wp_filter_post_kses');
294
 
295
  $client = new Lingotek_API();
296
-
297
  $translation = $client->get_translation($this->document_id, $locale, $this->source);
298
-
299
- if (!$translation || $this->translationNotReady( json_decode($translation, true) )) return; // If the request failed.
300
-
301
  $translation = json_decode($translation, true); // wp_insert_post expects array
302
 
303
  self::$creating_translation = true;
@@ -387,7 +385,7 @@ class Lingotek_Group_Post extends Lingotek_Group {
387
  *
388
  * @param array $translation the array returned from TMS.
389
  */
390
- private function translationNotReady($translation) {
391
  $trimmed_title = trim( $translation['post']['post_title'] );
392
  $trimmed_content = trim( $translation['post']['post_content'] );
393
  $trimmed_excerpt = trim($translation['post']['post_excerpt'] );
@@ -436,7 +434,7 @@ class Lingotek_Group_Post extends Lingotek_Group {
436
  * @return bool
437
  */
438
  public function is_automatic_upload() {
439
- return 'automatic' == Lingotek_Model::get_profile_option('upload', get_post_type($this->source), $this->get_source_language(), false, $this->source);
440
  }
441
 
442
  /*
293
  remove_filter('content_filtered_save_pre', 'wp_filter_post_kses');
294
 
295
  $client = new Lingotek_API();
296
+
297
  $translation = $client->get_translation($this->document_id, $locale, $this->source);
298
+ if (!$translation || $this->translation_not_ready( json_decode($translation, true) )) return; // If the request failed.
 
 
299
  $translation = json_decode($translation, true); // wp_insert_post expects array
300
 
301
  self::$creating_translation = true;
385
  *
386
  * @param array $translation the array returned from TMS.
387
  */
388
+ private function translation_not_ready($translation) {
389
  $trimmed_title = trim( $translation['post']['post_title'] );
390
  $trimmed_content = trim( $translation['post']['post_content'] );
391
  $trimmed_excerpt = trim($translation['post']['post_excerpt'] );
434
  * @return bool
435
  */
436
  public function is_automatic_upload() {
437
+ return 'automatic' == Lingotek_Model::get_profile_option('upload', get_post_type($this->source), $this->get_source_language(), false, $this->source) && parent::is_automatic_upload();
438
  }
439
 
440
  /*
include/group-string.php CHANGED
@@ -177,7 +177,7 @@ class Lingotek_Group_String extends Lingotek_Group {
177
  * @return bool
178
  */
179
  public function is_automatic_upload() {
180
- return 'automatic' == Lingotek_Model::get_profile_option('upload', 'string', $this->get_source_language());
181
  }
182
 
183
  /*
177
  * @return bool
178
  */
179
  public function is_automatic_upload() {
180
+ return 'automatic' == Lingotek_Model::get_profile_option('upload', 'string', $this->get_source_language()) && parent::is_automatic_upload();
181
  }
182
 
183
  /*
include/group-term.php CHANGED
@@ -168,7 +168,7 @@ class Lingotek_Group_Term extends Lingotek_Group {
168
  * @return bool
169
  */
170
  public function is_automatic_upload() {
171
- return 'automatic' == Lingotek_Model::get_profile_option('upload', $this->type, $this->get_source_language());
172
  }
173
 
174
  /*
168
  * @return bool
169
  */
170
  public function is_automatic_upload() {
171
+ return 'automatic' == Lingotek_Model::get_profile_option('upload', $this->type, $this->get_source_language()) && parent::is_automatic_upload();
172
  }
173
 
174
  /*
include/group.php CHANGED
@@ -176,19 +176,24 @@ abstract class Lingotek_Group {
176
  * @param string $locale
177
  */
178
  public function request_translation($locale) {
179
- $client = new Lingotek_API();
180
- $language = $this->pllm->get_language($locale);
181
- $workflow = Lingotek_Model::get_profile_option('workflow_id', $this->type, $this->get_source_language(), $language, $this->source);
182
- $args = $workflow ? array('workflow_id' => $workflow) : array();
183
-
184
- if (!$this->is_disabled_target($language) && empty($this->translations[$language->locale])) {
185
- // don't change translations to pending if the api call failed
186
- if ($client->request_translation($this->document_id, $language->locale, $args, $this->source)) {
187
- $this->status = 'current';
188
- $this->translations[$language->locale] = 'pending';
189
- }
 
 
 
 
190
 
191
- $this->save();
 
192
  }
193
  }
194
 
@@ -200,45 +205,61 @@ abstract class Lingotek_Group {
200
  * @param object $source_language language of the source
201
  */
202
  protected function _request_translations($source_language) {
 
203
  $type_id;
204
  $client = new Lingotek_API();
205
 
206
  foreach ($this->pllm->get_languages_list() as $lang) {
207
- if ($source_language->slug != $lang->slug && !$this->is_disabled_target($source_language, $lang) && empty($this->translations[$lang->locale])) {
208
- $workflow = Lingotek_Model::get_profile_option('workflow_id', $this->type, $source_language, $lang, $this->source);
209
- $args = $workflow ? array('workflow_id' => $workflow) : array();
210
-
211
- if ($this->type == 'string') {
212
- $type_id = $this->name;
213
- }
214
- else {
215
- $type_id = $this->source;
216
- }
217
- // don't change translations to pending if the api call failed
218
- if ($client->request_translation($this->document_id, $lang->locale, $args, $type_id)) {
219
-
220
- /**
221
- * This is a fix that reloads the object before editing & saving it. The problem
222
- * was that the callbacks were coming back before this method finished so the
223
- * $this->translations array was out of sync with what was in the database. We fix this
224
- * by reading the DB only when we need to -> make our edit -> save the edit. This keeps us from holding on to
225
- * old data and overwritting the new data.
226
- */
227
- if ('post_translations' === $this->taxonomy) {
228
- $this->load( PLL()->model->post->get_object_term((int) $this->source, 'post_translations') );
229
- } else if ('term_translations' === $this->taxonomy) {
230
- $this->load( PLL()->model->term->get_object_term((int) $this->source, 'term_translations') );
231
  }
232
- $this->status = 'current';
233
- if (!isset($this->translations[$lang->locale]) || isset($this->translations[$lang->locale]) && $this->translations[$lang->locale] != 'current') {
234
- $this->translations[$lang->locale] = 'pending';
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
235
  }
236
- $this->save();
237
  }
238
  }
239
  }
240
  }
241
 
 
 
 
 
 
 
 
 
 
 
242
  /*
243
  * checks the translations status of a document
244
  *
@@ -308,7 +329,7 @@ abstract class Lingotek_Group {
308
  */
309
  public function source_edited() {
310
  $this->status = 'edited';
311
- $this->translations = array_fill_keys(array_keys($this->translations), 'not-current');
312
  $this->save();
313
  }
314
 
@@ -321,7 +342,7 @@ abstract class Lingotek_Group {
321
  * @return bool
322
  */
323
  public function has_translation_status($status) {
324
- return array_intersect(array_keys($this->translations, $status), $this->pllm->get_languages_list(array('fields' => 'locale')));
325
  }
326
 
327
  /*
@@ -336,6 +357,22 @@ abstract class Lingotek_Group {
336
  return 'automatic' == Lingotek_Model::get_profile_option('download', $this->type, $this->get_source_language(), $this->pllm->get_language($locale), $this->source);
337
  }
338
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
339
  /*
340
  * checks if translation is disabled for a target language
341
  *
@@ -353,4 +390,135 @@ abstract class Lingotek_Group {
353
  return isset($profile['targets'][$language->slug]) && ('disabled' == $profile['targets'][$language->slug] || 'copy' == $profile['targets'][$language->slug]);
354
  }
355
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
356
  }
176
  * @param string $locale
177
  */
178
  public function request_translation($locale) {
179
+ $workflow = $this->get_workflow_object($this->get_source_language(), $locale, $this->type, $this->source);
180
+ if ($workflow->has_custom_request_procedure()) {
181
+ $workflow->do_custom_request();
182
+ } else {
183
+ $client = new Lingotek_API();
184
+ $language = $this->pllm->get_language($locale);
185
+ $workflow = Lingotek_Model::get_profile_option('workflow_id', $this->type, $this->get_source_language(), $language, $this->source);
186
+ $args = $workflow ? array('workflow_id' => $workflow) : array();
187
+
188
+ if (!$this->is_disabled_target($language) && empty($this->translations[$language->locale])) {
189
+ // don't change translations to pending if the api call failed
190
+ if ($client->request_translation($this->document_id, $language->locale, $args, $this->source)) {
191
+ $this->status = 'current';
192
+ $this->translations[$language->locale] = 'pending';
193
+ }
194
 
195
+ $this->save();
196
+ }
197
  }
198
  }
199
 
205
  * @param object $source_language language of the source
206
  */
207
  protected function _request_translations($source_language) {
208
+
209
  $type_id;
210
  $client = new Lingotek_API();
211
 
212
  foreach ($this->pllm->get_languages_list() as $lang) {
213
+ $workflow = $this->get_workflow_object($source_language, $lang->locale, $this->type, $this->source);
214
+ if ($workflow->has_custom_request_procedure()) {
215
+ $workflow->do_custom_request();
216
+ } else {
217
+ if ($source_language->slug != $lang->slug && !$this->is_disabled_target($source_language, $lang) && empty($this->translations[$lang->locale])) {
218
+ $workflow = Lingotek_Model::get_profile_option('workflow_id', $this->type, $source_language, $lang, $this->source);
219
+ $args = $workflow ? array('workflow_id' => $workflow) : array();
220
+
221
+ if ($this->type == 'string') {
222
+ $type_id = $this->name;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
223
  }
224
+ else {
225
+ $type_id = $this->source;
226
+ }
227
+ // don't change translations to pending if the api call failed
228
+ if ($client->request_translation($this->document_id, $lang->locale, $args, $type_id)) {
229
+
230
+ /**
231
+ * This is a fix that reloads the object before editing & saving it. The problem
232
+ * was that the callbacks were coming back before this method finished so the
233
+ * $this->translations array was out of sync with what was in the database. We fix this
234
+ * by reading the DB only when we need to -> make our edit -> save the edit. This keeps us from holding on to
235
+ * old data and overwritting the new data.
236
+ */
237
+ if ('post_translations' === $this->taxonomy) {
238
+ $this->load( PLL()->model->post->get_object_term((int) $this->source, 'post_translations') );
239
+ } else if ('term_translations' === $this->taxonomy) {
240
+ $this->load( PLL()->model->term->get_object_term((int) $this->source, 'term_translations') );
241
+ }
242
+ $this->status = 'current';
243
+ if (!isset($this->translations[$lang->locale]) || isset($this->translations[$lang->locale]) && $this->translations[$lang->locale] != 'current') {
244
+ $this->translations[$lang->locale] = 'pending';
245
+ }
246
+ $this->save();
247
  }
 
248
  }
249
  }
250
  }
251
  }
252
 
253
+ /**
254
+ * Publicly exposes the safe_translation_status_update method that allows us to safely update
255
+ * translation statuses. This method is used when a request translation call is made to bridge and that
256
+ * translation was requested successfully.
257
+ */
258
+ public function update_translation_status($locale, $status)
259
+ {
260
+ $this->safe_translation_status_update($locale, $status);
261
+ }
262
+
263
  /*
264
  * checks the translations status of a document
265
  *
329
  */
330
  public function source_edited() {
331
  $this->status = 'edited';
332
+ // $this->translations = array_fill_keys(array_keys($this->translations), 'not-current');
333
  $this->save();
334
  }
335
 
342
  * @return bool
343
  */
344
  public function has_translation_status($status) {
345
+ return isset($this->translations) && array_intersect(array_keys($this->translations, $status), $this->pllm->get_languages_list(array('fields' => 'locale')));
346
  }
347
 
348
  /*
357
  return 'automatic' == Lingotek_Model::get_profile_option('download', $this->type, $this->get_source_language(), $this->pllm->get_language($locale), $this->source);
358
  }
359
 
360
+ public function is_automatic_upload() {
361
+ $workflow = $this->get_workflow_object($this->get_source_language(), false, $this->type, $this->source);
362
+ $can_auto_upload = $workflow->auto_upload_allowed();
363
+ if ($can_auto_upload) {
364
+ /**
365
+ * Check each of the translations and if one of them doesn't allow automatic upload then we don't auto upload the doc.
366
+ */
367
+ foreach ($this->translations as $locale => $progress) {
368
+ $workflow = $this->get_workflow_object($this->get_source_language(), $locale, $this->type, $this->source);
369
+ $can_auto_upload = $can_auto_upload && $workflow->auto_upload_allowed();
370
+ }
371
+ }
372
+
373
+ return $can_auto_upload;
374
+ }
375
+
376
  /*
377
  * checks if translation is disabled for a target language
378
  *
390
  return isset($profile['targets'][$language->slug]) && ('disabled' == $profile['targets'][$language->slug] || 'copy' == $profile['targets'][$language->slug]);
391
  }
392
  }
393
+
394
+ /**
395
+ * Goes through the source document and all locales and calls the pre_upload_to_lingotek() on the Workflow object unless
396
+ * a locale has been disabled.
397
+ *
398
+ * @param string $item_id
399
+ * @param string $type
400
+ * @param object $source_language
401
+ * @return void
402
+ */
403
+ public function pre_upload_to_lingotek($item_id, $type, $source_language, $item_type) {
404
+ $workflow = $this->get_workflow_object($source_language, false, $type, $item_id);
405
+ $workflow->pre_upload_to_lingotek($item_id, $item_type);
406
+ foreach ($this->pllm->get_languages_list() as $lang) {
407
+ if ($this->_is_disabled_target($lang, $type, $item_id)) {
408
+ continue;
409
+ }
410
+ $workflow = $this->get_workflow_object($source_language, $lang->locale, $type, $item_id);
411
+ $workflow->pre_upload_to_lingotek($item_id, $item_type);
412
+ }
413
+ }
414
+
415
+ /**
416
+ * Goes through the source document and all locales and calls the save_post_hook() on the Workflow object unless
417
+ * a locale has been disabled.
418
+ *
419
+ * @param string $item_id
420
+ * @param string $type
421
+ * @param object $source_language
422
+ * @return void
423
+ */
424
+ public function pre_save_post($item_id, $type, $source_language) {
425
+ $workflow = $this->get_workflow_object($source_language, false, $type, $item_id);
426
+ $workflow->save_post_hook();
427
+ foreach ($this->pllm->get_languages_list() as $lang) {
428
+ if ($this->_is_disabled_target($lang, $type, $item_id)) {
429
+ continue;
430
+ }
431
+ $workflow = $this->get_workflow_object($source_language, $lang->locale, $type, $item_id);
432
+ $workflow->save_post_hook();
433
+ }
434
+ }
435
+
436
+ /**
437
+ * Goes through the source document and all locales and calls the save_term_hook() on the Workflow object unless
438
+ * a locale has been disabled.
439
+ *
440
+ * @param string $item_id
441
+ * @param string $type
442
+ * @param object $source_language
443
+ * @return void
444
+ */
445
+ public function pre_save_terms($item_id, $type, $source_language) {
446
+ $workflow = $this->get_workflow_object($source_language, false, $type, $item_id);
447
+ $workflow->save_term_hook();
448
+ foreach ($this->pllm->get_languages_list() as $lang) {
449
+ if ($this->_is_disabled_target($lang, $type, $item_id)) {
450
+ continue;
451
+ }
452
+ $workflow = $this->get_workflow_object($source_language, $lang->locale, $type, $item_id);
453
+ $workflow->save_term_hook();
454
+ }
455
+ }
456
+
457
+ public function get_custom_in_progress_icon($language) {
458
+ $workflow = $this->get_workflow_object($this->get_source_language(), $language->locale, $this->type, $this->source);
459
+ return $workflow->get_custom_in_progress_icon();
460
+ }
461
+
462
+ /**
463
+ * Checks the source language and all of its target language's workflows to determine whether a bulk translation request is allowed.
464
+ * If one or more of the workflows return true on has_custom_request_procedure() then the bulk translation request will be aborted.
465
+ *
466
+ * @param object $source_language
467
+ * @param string $type
468
+ * @param string $item_id
469
+ * @return boolean
470
+ */
471
+ private function can_bulk_request_translations($source_language, $type, $item_id) {
472
+ $workflow = $this->get_workflow_object($source_language, false, $type, $item_id);
473
+ if ($workflow->has_custom_request_procedure()) { return false; }
474
+
475
+ foreach ($this->pllm->get_languages_list() as $lang) {
476
+ if ($this->_is_disabled_target($lang, $type, $item_id)) {
477
+ continue;
478
+ }
479
+ $workflow = $this->get_workflow_object($source_language, $lang->locale, $type, $item_id);
480
+ if ($workflow->has_custom_request_procedure()) { return false; }
481
+ }
482
+
483
+ return true;
484
+ }
485
+
486
+ /**
487
+ * Instantiates and returns a workflow object. If only the source language is passed in then it will return the workflow object
488
+ * for the source locale; however, if a locale is passed in with the source language then a workflow object will be returned
489
+ * for the locale.
490
+ *
491
+ * @param string $source_language
492
+ * @param boolean | string $locale
493
+ * @param string $type
494
+ * @param string $item_id
495
+ * @return void
496
+ */
497
+ private function get_workflow_object( $source_language, $locale = false, $type, $item_id ) {
498
+ $target_language = ($locale) ? $this->pllm->get_language($locale) : false;
499
+ $source_language = (!$source_language) ? PLL()->model->post->get_language( $this->source ) : $source_language;
500
+ $workflow_id;
501
+ if ($type === 'post') {
502
+ $post = ($item_id) ? get_post($item_id) : get_post( $this->source );
503
+ $workflow_id = Lingotek_Model::get_profile_option( 'workflow_id', $post->post_type, $source_language, $target_language , $this->source );
504
+ } else {
505
+ $workflow_id = Lingotek_Model::get_profile_option( 'workflow_id', $type, $source_language, $target_language );
506
+ }
507
+ $workflow = Lingotek_Workflow_Factory::get_workflow_instance( $workflow_id );
508
+ return $workflow;
509
+ }
510
+
511
+ /**
512
+ * Checks if a target language has been disabled. Is different than the other is_disabled_target method by
513
+ * allowing the caller to supply all of the arguments used.
514
+ *
515
+ * @param object $target_language
516
+ * @param string $type
517
+ * @param string $item_id
518
+ * @return void
519
+ */
520
+ private function _is_disabled_target($target_language, $type, $item_id) {
521
+ $profile = Lingotek_Model::get_profile($type, $target_language, $item_id);
522
+ return isset($profile['targets'][$target_language->slug]) && ('disabled' == $profile['targets'][$target_language->slug] || 'copy' == $profile['targets'][$target_language->slug]);
523
+ }
524
  }
include/http.php CHANGED
@@ -46,12 +46,12 @@ class Lingotek_HTTP {
46
  *
47
  * @since 0.1
48
  */
49
- public function post($url, $args = array()) {
50
  Lingotek::log("POST " . $url);
51
  if (!empty($args)) {
52
  Lingotek::log($args);
53
  }
54
- return wp_remote_post($url, array('headers' => $this->headers, 'body' => $args, 'timeout' => self::TIMEOUT));
55
  }
56
 
57
  /*
46
  *
47
  * @since 0.1
48
  */
49
+ public function post($url, $args = array(), $custom_timeout = false) {
50
  Lingotek::log("POST " . $url);
51
  if (!empty($args)) {
52
  Lingotek::log($args);
53
  }
54
+ return wp_remote_post($url, array('headers' => $this->headers, 'body' => $args, 'timeout' => ($custom_timeout) ? $custom_timeout : self::TIMEOUT));
55
  }
56
 
57
  /*
include/model.php CHANGED
@@ -174,7 +174,7 @@ class Lingotek_Model {
174
  */
175
  static public function get_profile_option($item, $type, $source_language, $target_language = false, $post_id = null) {
176
  $profile = self::get_profile($type, $source_language, $post_id);
177
- if ('disabled' == $profile['profile'])
178
  return false;
179
 
180
  if (!empty($target_language) && isset($profile['targets'][$target_language->slug]) && !empty($profile['custom'][$item][$target_language->slug]))
@@ -182,7 +182,7 @@ class Lingotek_Model {
182
 
183
  if (!empty($profile[$item]))
184
  return $profile[$item];
185
-
186
  $defaults = get_option('lingotek_defaults');
187
  return $defaults[$item];
188
  }
@@ -293,6 +293,15 @@ class Lingotek_Model {
293
  return;
294
 
295
  $profile = self::get_profile($post->post_type, $language, $post_id);
 
 
 
 
 
 
 
 
 
296
  if ('disabled' == $profile['profile'])
297
  return;
298
 
@@ -357,6 +366,14 @@ class Lingotek_Model {
357
  if ('disabled' == $profile['profile'])
358
  return;
359
 
 
 
 
 
 
 
 
 
360
  $client = new Lingotek_API();
361
 
362
  $params = array(
174
  */
175
  static public function get_profile_option($item, $type, $source_language, $target_language = false, $post_id = null) {
176
  $profile = self::get_profile($type, $source_language, $post_id);
177
+ if ('disabled' === $profile['profile'] || is_object($target_language) && isset($profile['targets'][$target_language->slug]) && 'disabled' === $profile['targets'][$target_language->slug])
178
  return false;
179
 
180
  if (!empty($target_language) && isset($profile['targets'][$target_language->slug]) && !empty($profile['custom'][$item][$target_language->slug]))
182
 
183
  if (!empty($profile[$item]))
184
  return $profile[$item];
185
+
186
  $defaults = get_option('lingotek_defaults');
187
  return $defaults[$item];
188
  }
293
  return;
294
 
295
  $profile = self::get_profile($post->post_type, $language, $post_id);
296
+
297
+ /**
298
+ * Customized workflows have the option to do any sort of pre-processing before a document is uploaded to lingotek.
299
+ */
300
+ $document = $this->get_group('post', $post_id);
301
+ if ($document) {
302
+ $document->pre_upload_to_lingotek($post_id, $post->post_type, $language, 'post');
303
+ }
304
+
305
  if ('disabled' == $profile['profile'])
306
  return;
307
 
366
  if ('disabled' == $profile['profile'])
367
  return;
368
 
369
+ /**
370
+ * Customized workflows have the option to do any sort of pre-processing before a document is uploaded to lingotek.
371
+ */
372
+ $document = $this->get_group('term', $term_id);
373
+ if ($document) {
374
+ $document->pre_upload_to_lingotek($term_id, $taxonomy, $language, 'term');
375
+ }
376
+
377
  $client = new Lingotek_API();
378
 
379
  $params = array(
js/updater.js CHANGED
@@ -24,7 +24,7 @@ jQuery(document).ready(function($) {
24
  setInterval(function(){
25
  var rows = $('#the-list').find('tr');
26
  $(rows).each(function(){
27
- if($(this).attr('id').length > 1){
28
  var id = $(this).attr('id');
29
  var object_id = id.replace( /^\D+/g, '');
30
  current_ids[object_id] = object_id;
@@ -133,12 +133,20 @@ jQuery(document).ready(function($) {
133
  }
134
 
135
  function updateWorkbenchIcon(td, data, key, locale, title, icon){
 
 
 
 
 
 
 
 
136
  $(td).find('.pll_icon_edit').remove();
137
  $(td).find('.lingotek-color').remove();
138
  var request_link = $('<a></a>').attr('href', data[key][locale]['workbench_link'])
139
  .attr('title',title)
140
  .attr('target','_blank')
141
- .addClass('lingotek-color dashicons dashicons-' + icon);
142
  $(td).prepend(request_link);
143
  }
144
 
@@ -199,11 +207,15 @@ jQuery(document).ready(function($) {
199
  + '&noheader=1'
200
  + '&_wpnonce=' + data['upload_nonce'])
201
  .attr('title','Upload Now')
202
- .addClass('lingotek-color dashicons dashicons-upload');
203
  $(td).prepend(request_link);
204
  }
205
 
206
  function updateIndicator(td, data, key, locale, action, title, dashicon){
 
 
 
 
207
  $(td).find('.lingotek-color').remove();
208
  var request_link = $('<a></a>').attr('href', relative_url
209
  + page_params + 'document_id=' + data[key]['doc_id']
@@ -212,7 +224,7 @@ jQuery(document).ready(function($) {
212
  + '&noheader=1'
213
  + '&_wpnonce='+data[action + '_nonce'])
214
  .attr('title', title)
215
- .addClass('lingotek-color dashicons dashicons-' + dashicon);
216
  $(td).prepend(request_link);
217
  }
218
 
24
  setInterval(function(){
25
  var rows = $('#the-list').find('tr');
26
  $(rows).each(function(){
27
+ if($(this).attr('id') && $(this).attr('id').length > 1){
28
  var id = $(this).attr('id');
29
  var object_id = id.replace( /^\D+/g, '');
30
  current_ids[object_id] = object_id;
133
  }
134
 
135
  function updateWorkbenchIcon(td, data, key, locale, title, icon){
136
+ if ('clock' === icon && $(td).find('.lingotek-professional-icon').length > 0)
137
+ {
138
+ return;
139
+ }
140
+ else
141
+ {
142
+ $(td).find('.lingotek-professional-icon').remove();
143
+ }
144
  $(td).find('.pll_icon_edit').remove();
145
  $(td).find('.lingotek-color').remove();
146
  var request_link = $('<a></a>').attr('href', data[key][locale]['workbench_link'])
147
  .attr('title',title)
148
  .attr('target','_blank')
149
+ .addClass('lingotek-color dashicons dashicons-' + icon + ' dashicons-' + icon + '-lingotek');
150
  $(td).prepend(request_link);
151
  }
152
 
207
  + '&noheader=1'
208
  + '&_wpnonce=' + data['upload_nonce'])
209
  .attr('title','Upload Now')
210
+ .addClass('lingotek-color dashicons dashicons-upload dashicons-upload-lingotek');
211
  $(td).prepend(request_link);
212
  }
213
 
214
  function updateIndicator(td, data, key, locale, action, title, dashicon){
215
+ if ('download' === dashicon && $(td).find('.lingotek-professional-icon').length > 0)
216
+ {
217
+ $(td).find('.lingotek-professional-icon').remove();
218
+ }
219
  $(td).find('.lingotek-color').remove();
220
  var request_link = $('<a></a>').attr('href', relative_url
221
  + page_params + 'document_id=' + data[key]['doc_id']
224
  + '&noheader=1'
225
  + '&_wpnonce='+data[action + '_nonce'])
226
  .attr('title', title)
227
+ .addClass('lingotek-color dashicons dashicons-' + dashicon + ' dashicons-' + dashicon + '-lingotek');
228
  $(td).prepend(request_link);
229
  }
230
 
js/workflow/professional-workflow-account.js ADDED
@@ -0,0 +1,62 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ jQuery(document).ready(function() {
2
+ var twice = false;
3
+ jQuery(document).on('tb_unload', function(event) {
4
+ if (twice)
5
+ {
6
+ console.log('unload');
7
+ tear_down();
8
+ twice = false;
9
+ }
10
+ else
11
+ {
12
+ twice = true;
13
+ }
14
+ });
15
+
16
+ var timeout = false;
17
+
18
+ set_up();
19
+
20
+
21
+ function set_up()
22
+ {
23
+ payment_method_click_listener();
24
+ timeout = false;
25
+ }
26
+
27
+ function tear_down()
28
+ {
29
+ if (timeout)
30
+ {
31
+ clearTimeout(timeout);
32
+ }
33
+ payment_method_click_listener_off();
34
+ set_up();
35
+ }
36
+
37
+ function payment_method_click_listener()
38
+ {
39
+ jQuery('#professional-payment-info-link').on('click', function(e) {
40
+ console.log('clicker');
41
+ e.preventDefault();
42
+ tb_show('<img src="' + modal_vars.icon_url +'" style="padding-top:10px; display:inline-block"><span style="position:absolute; padding-top: 15px;"class="Upgrade-to-Lingotek">Lingotek Professional Translation Services</span>', '#TB_inline?width=800&height=400&inlineId=modal-window-id-' + account_vars.modal_id);
43
+ jQuery('#TB_title').css('height','55px');
44
+ jQuery('#TB_title').css('background-color','#3c3c3c');
45
+ jQuery('.tb-close-icon').css('color','white');
46
+ set_payment_portal_timeout();
47
+ });
48
+ }
49
+
50
+ function payment_method_click_listener_off()
51
+ {
52
+ jQuery('#professional-payment-info-link').off('click');
53
+ }
54
+
55
+
56
+ function set_payment_portal_timeout()
57
+ {
58
+ timeout = setTimeout(function() {
59
+ window.location = account_vars.bridge_payment + '?redirect_url=' + encodeURIComponent(window.location);
60
+ },3000);
61
+ }
62
+ });
js/workflow/professional-workflow-defaults.js ADDED
@@ -0,0 +1,160 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ jQuery(document).ready(function() {
2
+
3
+ if (Workflow.modals.get_url_parameter('success', window.location) &&
4
+ Workflow.modals.get_url_parameter('page', window.location) === 'lingotek-translation_settings' &&
5
+ Workflow.modals.get_url_parameter('sm', window.location) === 'defaults') {
6
+ jQuery('#workflow_id').attr('value','ab6c522a-7645-4317-9284-3fbddf516151');
7
+ jQuery('#submit').trigger('click');
8
+ }
9
+
10
+ var twice = false;
11
+ jQuery(document).on('tb_unload', function(event) {
12
+ if (twice)
13
+ {
14
+ console.log('unload');
15
+ tear_down();
16
+ twice = false;
17
+ }
18
+ else
19
+ {
20
+ twice = true;
21
+ }
22
+ });
23
+
24
+ var timeout = false;
25
+ // var last_select = true;
26
+
27
+
28
+ set_up();
29
+
30
+ function set_up()
31
+ {
32
+ // last_select = true;
33
+ add_payment_later_listener();
34
+ workflow_change_listener();
35
+ jQuery('.payment-portal-image').prop('src', professional_vars.translation_icon);
36
+ jQuery('.payment-portal-loading').prop('src', professional_vars.loading_gif);
37
+ timeout = false;
38
+ jQuery(document).on('click', '.edit-payment-method-already-setup, .edit-payment-method-not-setup', edit_payment_info_click_listener);
39
+ }
40
+
41
+ function edit_payment_info_click_listener(e)
42
+ {
43
+ e.preventDefault();
44
+ show_base_modal();
45
+ show_payment_portal_loading_screen();
46
+ set_payment_portal_timeout();
47
+ }
48
+
49
+ function tear_down()
50
+ {
51
+ if (timeout)
52
+ {
53
+ clearTimeout(timeout);
54
+ }
55
+ // if (last_select)
56
+ // {
57
+ // lastSel.attr('selected', true);
58
+ // }
59
+ jQuery.each(Workflow.workflows, function(key, value) {
60
+ jQuery('#yes-' + key).off();
61
+ });
62
+ jQuery(document).off('click', '.edit-payment-method-already-setup, .edit-payment-method-not-setup', edit_payment_info_click_listener);
63
+ add_payment_later_listener_off();
64
+ workflow_change_listener_off();
65
+ show_normal_screen();
66
+
67
+ set_up();
68
+ }
69
+
70
+
71
+ function show_normal_screen()
72
+ {
73
+ jQuery('#TB_ajaxContent').find('*').not('.payment-portal-element').show();
74
+ jQuery('.payment-portal-element').hide();
75
+ }
76
+
77
+ function add_payment_later_listener()
78
+ {
79
+ jQuery('#no-' + professional_vars.workflow_id).on('click', function() {
80
+ console.log('click');
81
+ // last_select = false;
82
+ Workflow.modals.close_modal('TB_closeWindowButton');
83
+ });
84
+ }
85
+
86
+ function add_payment_later_listener_off()
87
+ {
88
+ jQuery('#no-' + professional_vars.workflow_id).off();
89
+ }
90
+
91
+ function workflow_change_listener()
92
+ {
93
+ jQuery('#workflow_id, select[id^="custom[workflow_id]"]').on('change', function(e) {
94
+ if (Workflow.workflows.hasOwnProperty(this.value))
95
+ {
96
+ var workflow = this.value;
97
+
98
+ if (!professional_vars.payment_info.payment_info.payment_profile)
99
+ {
100
+ modal_init();
101
+ jQuery(this).after('&nbsp;&nbsp;<a class="edit-payment-info edit-payment-method-not-setup" href="#">Setup Lingotek Payment Method</a>');
102
+ jQuery('#edit-payment-method-not-setup').on('click', function() {
103
+ modal_init();
104
+ show_payment_portal_loading_screen();
105
+ set_payment_portal_timeout();
106
+ });
107
+ }
108
+ else
109
+ {
110
+ jQuery(this).after('&nbsp;&nbsp;<a class="edit-payment-info edit-payment-method-already-setup" href="#">Edit Lingotek Payment Method</a>');
111
+ }
112
+ }
113
+ else
114
+ {
115
+ console.log('remove');
116
+ jQuery(this).closest('td').find('.edit-payment-method-already-setup, .edit-payment-method-not-setup').remove();
117
+ }
118
+ });
119
+ }
120
+
121
+ function workflow_change_listener_off()
122
+ {
123
+ jQuery('#workflow_id, select[id^="custom[workflow_id]"]').off();
124
+ }
125
+
126
+ function modal_init()
127
+ {
128
+ jQuery('#yes-' + professional_vars.workflow_id).on('click', function() {
129
+ show_payment_portal_loading_screen();
130
+ set_payment_portal_timeout();
131
+ });
132
+ show_base_modal();
133
+ show_normal_screen();
134
+
135
+ }
136
+
137
+ function set_payment_portal_timeout()
138
+ {
139
+ timeout = setTimeout(function() {
140
+ window.location = professional_vars.bridge_payment + '?redirect_url=' + encodeURIComponent(window.location);
141
+ },3000);
142
+ }
143
+
144
+ function show_base_modal()
145
+ {
146
+ tb_show('<img src="' + modal_vars.icon_url +'" style="padding-top:10px; display:inline-block"><span style="position:absolute; padding-top: 15px;"class="Upgrade-to-Lingotek">Lingotek Professional Translation Services</span>', '#TB_inline?width=800&height=400&inlineId=modal-window-id-' + professional_vars.workflow_id);
147
+ jQuery('#TB_title').css('height','55px');
148
+ jQuery('#TB_title').css('background-color','#3c3c3c');
149
+ jQuery('.tb-close-icon').css('color','white');
150
+ }
151
+
152
+ function show_payment_portal_loading_screen()
153
+ {
154
+ jQuery('#TB_ajaxContent').find('*').not('.payment-portal-element').hide();
155
+ jQuery('.payment-portal-element').show();
156
+ }
157
+ // var lastSel = jQuery('#workflow_id option:selected');
158
+ // try new rollback here.
159
+
160
+ });
js/workflow/professional-workflow.js CHANGED
@@ -1,29 +1,1861 @@
1
  jQuery(document).ready(function() {
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
2
  var yes = '#yes-' + workflow_vars.id;
3
  var no = '#no-' + workflow_vars.id;
4
  var yes_request = yes + '-request';
5
  var no_request = no + '-request';
6
 
7
- jQuery(".dashicons-upload").on('click', function(event){
8
- event.preventDefault();
9
- jQuery(this).addClass('thickbox');
10
- var url = Workflow.modals.replace_href(this);
11
- jQuery(yes).attr('href', url);
12
- jQuery(this).attr('href', '#TB_inline?width=500&height=300&inlineId=modal-window-id-' + workflow_vars.id);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
13
  });
14
 
15
- jQuery(".dashicons-plus").on('click', function(event){
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
16
  event.preventDefault();
17
- jQuery(this).addClass('thickbox');
 
18
  var url = Workflow.modals.replace_href(this);
19
- jQuery(yes_request).attr('href', url);
20
- jQuery(this).attr('href', '#TB_inline?width=500&height=300&inlineId=modal-window-id-' + workflow_vars.id + '-request');
21
- });
22
 
23
- jQuery(yes + ',' + yes_request).on('click', function() {
24
- Workflow.modals.close_modal('TB_closeWindowButton');
25
- });
26
- jQuery(no + ',' + no_request).on('click', function() {
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
27
  Workflow.modals.close_modal('TB_closeWindowButton');
28
- });
29
- })
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
  jQuery(document).ready(function() {
2
+
3
+ /**
4
+ * Re-attaches event handlers to icons every second. This allows the professional workflow to work with the
5
+ * auto updater.js
6
+ */
7
+ setInterval(function() {
8
+ if (jQuery('#TB_ajaxWindowTitle').length === 0 )
9
+ {
10
+ tear_down();
11
+ }
12
+ else
13
+ {
14
+ if (jQuery('#TB_window').find('.request-table').length > 0)
15
+ {
16
+ jQuery('#TB_window').removeAttr('style');
17
+ jQuery('#TB_window').addClass('ltk-thickbox');
18
+ }
19
+ else if (jQuery('#TB_window').find('.professional-upload-warning-header-container').length > 0)
20
+ {
21
+ jQuery('#TB_window').removeAttr('style');
22
+ jQuery('#TB_window').addClass('ltk-thickbox-warning');
23
+ }
24
+ }
25
+ },1000);
26
+
27
+ var up = false;
28
+
29
+ const MINIMUM = 59.99;
30
+ const DEFAULT_MINIMUM_DELIVERY_DAYS = 3;
31
+ const DEFAULT_MAXIMUM_DELIVERY_DAYS = 5;
32
+ const DELIVERY_WORDS_INCREASE = 2000;
33
  var yes = '#yes-' + workflow_vars.id;
34
  var no = '#no-' + workflow_vars.id;
35
  var yes_request = yes + '-request';
36
  var no_request = no + '-request';
37
 
38
+ /**
39
+ * This is a reduntant variable that ensures that a customer is not charged twice due to a duplicate API call.
40
+ */
41
+ var dispatched = false;
42
+
43
+ /**
44
+ * The Wordpress tb_unload event fires twice. This code ensures that the reset code only runs once.
45
+ */
46
+ var twice = false;
47
+ jQuery(document).on('tb_unload', function(event) {
48
+ if (twice)
49
+ {
50
+ console.log('unload');
51
+ tear_down();
52
+ twice = false;
53
+ dispatched = false;
54
+ }
55
+ else
56
+ {
57
+ twice = true;
58
+ }
59
+ });
60
+
61
+
62
+ var global_locale_list = [];
63
+ var global_ajax_requests_list = [];
64
+
65
+ /**
66
+ * This is a failsafe to guard against the user attempting to click 'apply' rapidly when executing bulk actions.
67
+ * When a bulk action has started this flag is switched to true so that a bulk action cannot be requested until the tear_down()
68
+ * method has been called when the modal is destroyed.
69
+ */
70
+ var start_bulk = false;
71
+
72
+ /**
73
+ * This is a failsafe to guard against the user closing the modal after ajax requests have been launched. We don't want any left-over
74
+ * ajax requests to come back and alter the modal. This acts as a sort of 'lock' so that any any ajax requests coming back aren't allowed to
75
+ * touch the modal.
76
+ */
77
+ var abort_ajax = false;
78
+
79
+ var buy_now_clicked = false;
80
+ /**
81
+ * As requests come back this buffer is filled with rows to render.
82
+ */
83
+ var document_id_to_row_buffer = {};
84
+
85
+ var document_id_to_post_id = {};
86
+
87
+ var loading_exceptions = '.payment-portal-element, .row-table-hidden, .header-table-hidden, .requesting-element, .payment-not-setup, .payment-method-setup, .professional-translation-request-success-element, .professional-translation-request-error-element';
88
+
89
+ var global_timeout = false;
90
+
91
+ set_up(); // set event listeners.
92
+
93
+ /**
94
+ * Attaches event listeners to the upload and request icons.
95
+ *
96
+ */
97
+ function set_up()
98
+ {
99
+ init_handlers();
100
+ disable_buy_now_button();
101
+ disable_confirm_warning_button();
102
+ disable_confirm_warning_checkbox();
103
+ init_globals();
104
+ init_lock_flags();
105
+ modal_refresh();
106
+ }
107
+
108
+
109
+ /**
110
+ * Removes all listeners and re-attaches them. This needs to happen because
111
+ * all HTTP communication is happening via ajax so it is crucial that we don't
112
+ * leave the frontend in an invalid state.
113
+ *
114
+ */
115
+ function tear_down()
116
+ {
117
+ if (global_timeout)
118
+ {
119
+ clearTimeout(global_timeout);
120
+ }
121
+ global_timeout = false;
122
+ clear_ajax_requests();
123
+ detach_handlers();
124
+ clear_global_lists();
125
+ set_up();
126
+ check_buy_now_clicked();
127
+ }
128
+
129
+ function check_buy_now_clicked()
130
+ {
131
+ if (click_bulk_action)
132
+ {
133
+ jQuery('#doaction').trigger('click');
134
+ }
135
+ else if (buy_now_clicked)
136
+ {
137
+ location.reload();
138
+ }
139
+ click_bulk_action = false;
140
+ }
141
+
142
+ function clear_global_lists()
143
+ {
144
+ /**
145
+ * Clear all of our lists.
146
+ */
147
+ document_id_list = [];
148
+ // locale_list = [];
149
+ global_locale_list = [];
150
+ active_locale_list = [];
151
+ shown_headers = [];
152
+ shown_columns = {};
153
+ document_id_to_row_buffer = {};
154
+ document_id_to_post_id = {};
155
+ }
156
+
157
+ function detach_handlers()
158
+ {
159
+ jQuery(yes_request).off();
160
+ jQuery(no_request).off();
161
+ jQuery(yes).off();
162
+ jQuery(no).off();
163
+ jQuery('.checkable').off();
164
+ jQuery('#next-language-set').off();
165
+ jQuery('#doaction, #doaction2').off();
166
+ jQuery.each(item_ids.ids, function(item_id, valid_locales) {
167
+ get_post_or_taxonomy_row(item_id).find('.dashicons-plus-lingotek').each(function(index, element) {
168
+ var url = jQuery(element).attr('href');
169
+ var locale = Workflow.modals.get_url_parameter('locale', url);
170
+ if (is_valid_locale(locale, valid_locales))
171
+ {
172
+ Workflow.modals.replace_href(element);
173
+ jQuery(element).off();
174
+ }
175
+ });
176
+ get_post_or_taxonomy_row(item_id).find('.lingotek-request').off();
177
+ get_post_or_taxonomy_row(item_id).find('.lingotek-upload').each(function(index, element) {
178
+ jQuery(jQuery(element).children()[0]).off();
179
+ });
180
+
181
+ get_string_group_row(item_id).find('.dashicons-plus-lingotek').each(function(index, element) {
182
+ var url = jQuery(element).attr('href');
183
+ var locale = Workflow.modals.get_url_parameter('locale', url);
184
+ if (is_valid_locale(locale, valid_locales))
185
+ {
186
+ Workflow.modals.replace_href(element);
187
+ jQuery(element).off();
188
+ }
189
+ });
190
+ get_string_group_row(item_id).find('.lingotek-request').off();
191
+ get_string_group_row(item_id).find('.lingotek-upload').each(function(index, element) {
192
+ jQuery(jQuery(element).children()[0]).off();
193
+ });
194
+ });
195
+
196
+ jQuery.each(global_locale_list, function(index,value) {
197
+ jQuery(document).off('click', '.' + value + '-header');
198
+ jQuery('.' + value + '-header').remove();
199
+ });
200
+
201
+ jQuery.each(document_id_list, function(index,value) {
202
+ jQuery(document).off('click', '.' + value);
203
+ });
204
+
205
+ jQuery(document).off('click', '.checkable');
206
+
207
+ jQuery(document).off('ajaxStop');
208
+
209
+ jQuery(document).off('click','#yes-' + workflow_vars.workflow_id + '-request-add-payment');
210
+
211
+ jQuery('#bulk-lingotek-request').off();
212
+
213
+ jQuery('.dashicons-upload-lingotek').off();
214
+
215
+ terms_and_conditions_listener_off();
216
+ accept_terms_and_conditions_listener_off();
217
+ buy_now_listener_off();
218
+
219
+ documents_could_be_overwritten_handler_off();
220
+
221
+ }
222
+
223
+ function clear_ajax_requests()
224
+ {
225
+ /**
226
+ * Ajax requests are stored as they are fired. The ones that come back successfully remove themselves from the list. If there
227
+ * are any ajax requests left in this list then we know that they didn't finish when the modal was closed so we turn on our ajax lock and abort
228
+ * all of the left over requests.
229
+ */
230
+ jQuery.each(global_ajax_requests_list, function(index,request) {
231
+ abort_ajax = true;
232
+ request.abort();
233
+ console.log('abort');
234
+ });
235
+ }
236
+
237
+
238
+ function modal_refresh()
239
+ {
240
+ /**
241
+ * Removes any left over table items.
242
+ */
243
+ jQuery('.request-table-item').remove();
244
+ }
245
+
246
+ function init_lock_flags()
247
+ {
248
+ /**
249
+ * Reset our flags.
250
+ */
251
+ start_bulk = false;
252
+ abort_ajax = false;
253
+ }
254
+
255
+ function init_globals()
256
+ {
257
+ /**
258
+ * The enabled_langs property is an object that maps a wordpress locale to a lingotek locale.
259
+ * For compatibilty with older browsers we extract the lingotek locales this way.
260
+ */
261
+ for (var key in workflow_vars.enabled_langs)
262
+ {
263
+ if (Object.prototype.hasOwnProperty.call(workflow_vars.enabled_langs, key)) {
264
+ var val = workflow_vars.enabled_langs[key];
265
+ global_locale_list.push(val.lingotek_locale);
266
+ }
267
+ }
268
+
269
+ global_ajax_requests_list = [];
270
+
271
+ }
272
+
273
+
274
+
275
+
276
+ function init_handlers()
277
+ {
278
+ /**
279
+ * A list of post Ids are sent from the server indicating which posts have professional translation enabled.
280
+ * We iterate over that list and attach listeners to those icons.
281
+ */
282
+ jQuery.each(item_ids.ids, function(post_id, valid_locales) {
283
+ var row;
284
+ if (workflow_vars.curr_item_type === 'string')
285
+ {
286
+ row = get_string_group_row(post_id);
287
+ }
288
+ else
289
+ {
290
+ row = get_post_or_taxonomy_row(post_id);
291
+ }
292
+
293
+
294
+ row.find('.dashicons-plus-lingotek').each(function(index, element) {
295
+ var href = Workflow.modals.replace_href(element); /**jQuery(element).attr('href');*/
296
+ var locale = Workflow.modals.get_url_parameter('locale', href);
297
+ if (is_valid_locale(locale, valid_locales))
298
+ {
299
+ jQuery(element).off();
300
+ jQuery(element).on('click', request_handler);
301
+ var url = Workflow.modals.replace_href(element);
302
+ var doc_id = Workflow.modals.get_url_parameter('document_id', url);
303
+ document_id_to_post_id[doc_id] = post_id;
304
+ }
305
+
306
+ });
307
+
308
+
309
+
310
+ /**
311
+ * Attaches an event handler the the 'Request translations' row action.
312
+ */
313
+ row.find('.lingotek-request').on('click', request_translation_row_handler);
314
+
315
+
316
+ /**
317
+ * The 'lingotek-request' span tag wraps an href. We want to replace this href with '#' so that there is no way
318
+ * for it to get executed.
319
+ */
320
+ row.find('.lingotek-request').each(function(index, element) {
321
+ Workflow.modals.replace_href(jQuery(element).children()[0]);
322
+ });
323
+
324
+ row.find('.lingotek-upload').each(function(index, element) {
325
+ if (documents_could_be_overwritten(jQuery(element).children()[0]))
326
+ {
327
+ Workflow.modals.replace_href(jQuery(element).children()[0]);
328
+ jQuery( jQuery(element).children()[0] ).attr('onclick', '');
329
+ jQuery(jQuery(element).children()[0]).on('click', documents_could_be_overwritten_handler);
330
+ }
331
+ });
332
+
333
+ row.find('.dashicons-upload-lingotek').each(function(index, element) {
334
+ if (documents_could_be_overwritten(element))
335
+ {
336
+ Workflow.modals.replace_href(element);
337
+ jQuery(element).on('click', documents_could_be_overwritten_handler);
338
+ }
339
+ });
340
+ });
341
+
342
+ jQuery('#doaction, #doaction2').on('click', bulk_request_handler);
343
+ jQuery('#doaction, #doaction2').on('click', bulk_upload_handler);
344
+
345
+ jQuery(document).on('click','#yes-' + workflow_vars.workflow_id + '-request-add-payment', add_payment_method_handler);
346
+
347
+ jQuery('#professional-post-transaction-button, #professional-post-transaction-failure').on('click', function() {
348
+ Workflow.modals.close_modal('TB_closeWindowButton');
349
+ });
350
+ }
351
+
352
+ function is_valid_locale(locale, valid_locale_list)
353
+ {
354
+ return jQuery.inArray(locale, valid_locale_list) !== -1
355
+ }
356
+
357
+ function get_post_or_taxonomy_row(id)
358
+ {
359
+ return jQuery('#post-' + id + ', #tag-' + id);
360
+ }
361
+
362
+ function get_string_group_row(id)
363
+ {
364
+ return jQuery('#string-select-' + id).closest('tr')
365
+ }
366
+
367
+ function documents_could_be_overwritten(element)
368
+ {
369
+ return jQuery(element).closest('tr').find('.dashicons-download-lingotek, .lingotek-professional-icon').length > 0;
370
+ }
371
+
372
+ function documents_could_be_overwritten_handler(event)
373
+ {
374
+ Workflow.modals.show_modal(workflow_vars.workflow_id + '-warning', 'Lingotek Professional Translation Services', 400, 800);
375
+ jQuery(document).on('click', '#cancel-warning-' + workflow_vars.workflow_id + '-warning', function() {
376
+ Workflow.modals.close_modal('TB_closeWindowButton');
377
+ });
378
+
379
+ jQuery(document).on('click', '#professional-warning-checkbox', function() {
380
+ if (jQuery(this).prop('checked'))
381
+ {
382
+ enable_confirm_warning_button();
383
+ }
384
+ else
385
+ {
386
+ disable_confirm_warning_button();
387
+ }
388
+ });
389
+
390
+ var element = this;
391
+ jQuery(document).on('click', '#ok-warning-' + workflow_vars.workflow_id + '-warning', function() {
392
+ jQuery('#professional-warning-loading-spinner').show();
393
+ window.location = Workflow.modals.replace_href(element);
394
+ });
395
+ }
396
+
397
+ function enable_confirm_warning_button()
398
+ {
399
+ jQuery('#ok-warning-'+workflow_vars.workflow_id+'-warning').removeClass('professional-okay-warning-button-disabled');
400
+ jQuery('#ok-warning-'+workflow_vars.workflow_id+'-warning').addClass('professional-okay-warning-button');
401
+ jQuery('#professional-warning-okay-text').removeClass('ADD-PAYMENT-DISABLED').addClass('ADD-PAYMENT');
402
+ jQuery('#ok-warning-'+workflow_vars.workflow_id+'-warning').prop('disabled', false);
403
+ }
404
+
405
+ function disable_confirm_warning_button()
406
+ {
407
+ jQuery('#ok-warning-'+workflow_vars.workflow_id+'-warning').removeClass('professional-okay-warning-button');
408
+ jQuery('#ok-warning-'+workflow_vars.workflow_id+'-warning').addClass('professional-okay-warning-button-disabled');
409
+ jQuery('#professional-warning-okay-text').removeClass('ADD-PAYMENT').addClass('ADD-PAYMENT-DISABLED');
410
+ jQuery('#ok-warning-'+workflow_vars.workflow_id+'-warning').prop('disabled', true);
411
+ }
412
+
413
+ function disable_confirm_warning_checkbox()
414
+ {
415
+ jQuery('#professional-warning-checkbox').prop('checked', false);
416
+ }
417
+
418
+ function documents_could_be_overwritten_handler_off()
419
+ {
420
+ jQuery(document).off('click', '#cancel-warning-' + workflow_vars.workflow_id + '-warning');
421
+ jQuery(document).off('click', '#professional-warning-checkbox');
422
+ jQuery(document).off('click', '#ok-warning-' + workflow_vars.workflow_id + '-warning');
423
+ }
424
+
425
+ function add_payment_method_handler()
426
+ {
427
+ payment_portal_loading_screen();
428
+ global_timeout = setTimeout(function() {
429
+ window.location = workflow_vars.bridge_payment_redirect + '?redirect_url=' + encodeURIComponent(window.location);
430
+ },3000);
431
+ }
432
+
433
+ function terms_and_conditions_listener()
434
+ {
435
+ jQuery(document).on('click', '#terms-and-conditions-href', function() {
436
+ show_terms_and_conditions();
437
+ });
438
+ }
439
+
440
+ function terms_and_conditions_listener_off()
441
+ {
442
+ jQuery(document).off('click', '#terms-and-conditions-href');
443
+ jQuery(document).off('click', '#close-terms-and-conditions');
444
+
445
+ }
446
+
447
+ function show_terms_and_conditions()
448
+ {
449
+ var ajax_url = Workflow.modals.get_ajax_url('get_ltk_terms_and_conditions');
450
+ Workflow.modals.ajax_request('GET', ajax_url, {'_lingotek_nonce' : workflow_vars.nonce}, function(response) {
451
+ jQuery('.terms-and-conditions-content').html(response.data);
452
+ jQuery('.terms-and-conditions-content').find('ul').each(function (i, el) {
453
+ jQuery(el).replaceWith('<ol>' + jQuery(el).html() + '</ol>');
454
+ });
455
+ });
456
+ jQuery('#professional-table-content').hide();
457
+ jQuery('#professional-terms-and-conditions').show();
458
+ jQuery('#professional-terms-and-conditions').height(jQuery('#modal-body-'+ workflow_vars.workflow_id +'-request').height() - 50);
459
+
460
+ jQuery(document).on('click', '#close-terms-and-conditions', function() {
461
+ hide_terms_and_conditions();
462
+ });
463
+ }
464
+
465
+
466
+ function set_up_side_panel_height()
467
+ {
468
+ jQuery('#sidebar').height(jQuery('#modal-body-'+ workflow_vars.workflow_id +'-request').height() - 50);
469
+ }
470
+
471
+ function hide_terms_and_conditions()
472
+ {
473
+ jQuery('#professional-table-content').show();
474
+ jQuery('#professional-terms-and-conditions').hide();
475
+ }
476
+
477
+ function buy_now_listener()
478
+ {
479
+ jQuery(document).on('click', '#yes-'+ workflow_vars.workflow_id +'-request-buy-now', function() {
480
+ buy_now_clicked = true;
481
+ show_requesting_translation_screen();
482
+ request_translations();
483
+ });
484
+ }
485
+
486
+ function buy_now_listener_off()
487
+ {
488
+ jQuery(document).off('click', '#yes-'+ workflow_vars.workflow_id +'-request-buy-now');
489
+ }
490
+
491
+ function request_translations()
492
+ {
493
+ var translations = {};
494
+ jQuery.each(document_id_list, function(index, value) {
495
+ translations[value] = [];
496
+ });
497
+ jQuery('.checkable:checked').each(function(index, value) {
498
+ var class_string = jQuery(this).attr('class');
499
+ var doc_id = get_item_from_class(class_string, document_id_list);
500
+ var locale = get_item_from_class(class_string, global_locale_list);
501
+ if (jQuery.inArray(locale, translations[doc_id]) === -1)
502
+ {
503
+ translations[doc_id].push(locale);
504
+ }
505
+ });
506
+ console.log(translations);
507
+ ajax_request_bulk_translation(translations);
508
+ }
509
+
510
+ function ajax_request_bulk_translation(translations)
511
+ {
512
+ var ajax_url = Workflow.modals.get_ajax_url('request_professional_translation');
513
+ var total = jQuery('.lingotek-total-amount').html().slice(1).replace(',','');
514
+ var request_translation_body = {
515
+ 'ids' : document_id_to_post_id,
516
+ 'translations' : translations,
517
+ 'workflow_id' : workflow_vars.workflow_id,
518
+ 'lingotek_locale_to_wp_locale' : get_lingotek_locale_to_wp_locale_list(),
519
+ 'type' : workflow_vars.curr_item_type,
520
+ 'summary': get_translation_summary(),
521
+ 'total_estimate': total,
522
+ '_lingotek_nonce' : workflow_vars.nonce
523
+ };
524
+ var request = Workflow.modals.ajax_request('POST', ajax_url, request_translation_body, function(response) {
525
+ console.log(response);
526
+ if (response.data.transaction_approved)
527
+ {
528
+ show_display_invoice_screen_success(response);
529
+ }
530
+ else
531
+ {
532
+ show_error_screen();
533
+ }
534
+ global_ajax_requests_list.splice(global_ajax_requests_list.indexOf(request), 1);
535
+ });
536
+ global_ajax_requests_list.push(request);
537
+ }
538
+
539
+ function get_translation_summary()
540
+ {
541
+ var summary = [];
542
+ jQuery('.translation-summary-list-text-ltk').each(function(index,value) {
543
+ summary.push(jQuery(value).text());
544
+ });
545
+ return summary;
546
+ }
547
+
548
+
549
+ function accept_terms_and_conditions_listener()
550
+ {
551
+ jQuery(document).on('click', '#accept-terms-and-conditions-input', function() {
552
+ if (jQuery(this).prop('checked'))
553
+ {
554
+ enable_buy_now_button();
555
+ }
556
+ else
557
+ {
558
+ disable_buy_now_button();
559
+ }
560
+ });
561
+ }
562
+
563
+ function enable_buy_now_button()
564
+ {
565
+ jQuery('#yes-'+ workflow_vars.workflow_id +'-request-buy-now').removeClass('professional-action-button-disabled').addClass('professional-action-button');
566
+ jQuery('#professional-buy-now').removeClass('ADD-PAYMENT-DISABLED').addClass('ADD-PAYMENT');
567
+ jQuery('#yes-'+ workflow_vars.workflow_id +'-request-buy-now').prop('disabled', false);
568
+ }
569
+
570
+ function disable_buy_now_button()
571
+ {
572
+ jQuery('#yes-'+ workflow_vars.workflow_id +'-request-buy-now').addClass('professional-action-button-disabled').removeClass('professional-action-button');
573
+ jQuery('#professional-buy-now').addClass('ADD-PAYMENT-DISABLED').removeClass('ADD-PAYMENT');
574
+ jQuery('#yes-'+ workflow_vars.workflow_id +'-request-buy-now').prop('disabled', true);
575
+ jQuery('#accept-terms-and-conditions-input').prop('checked', false);
576
+ }
577
+
578
+ function accept_terms_and_conditions_listener_off()
579
+ {
580
+ jQuery(document).off('click', '#accept-terms-and-conditions-input');
581
+ }
582
+
583
+ /**
584
+ * Displays the first slide.
585
+ *
586
+ */
587
+ function show_requesting_translation_screen()
588
+ {
589
+ jQuery('#modal-body-'+workflow_vars.workflow_id+'-request').find('*').not('.requesting-element').hide();
590
+ jQuery('.requesting-element').show();
591
+ }
592
+
593
+ function show_display_invoice_screen_success(response)
594
+ {
595
+ jQuery('#modal-body-'+workflow_vars.workflow_id+'-request').find('*').not('.professional-translation-request-success-element').hide();
596
+ jQuery('#professional-translation-cost-success').html(escape_html( '$' + number_with_commas( response.data.total_price.toFixed(2) ) ));
597
+ jQuery('.professional-translation-request-success-element').show();
598
+ }
599
+
600
+ function show_error_screen()
601
+ {
602
+ jQuery('#modal-body-'+workflow_vars.workflow_id+'-request').find('*').not('.professional-translation-request-error-element').hide();
603
+ jQuery('.professional-translation-request-error-element').show();
604
+ }
605
+
606
+ function show_loading_error()
607
+ {
608
+ jQuery('#error-requesting-translation-ltk').text('There was an error requesting the price quotes.');
609
+ jQuery('#error-requesting-translation-ltk-2').text('Please verify that your document exists on Lingotek TMS.').css('font-size','16px');
610
+ }
611
+
612
+ /**
613
+ * Displays failure slide.
614
+ *
615
+ */
616
+ function showFailureSlide()
617
+ {
618
+ jQuery('#' + workflow_vars.workflow_id+ '-success').hide();
619
+ jQuery('#' + workflow_vars.workflow_id+ '-first').hide();
620
+ }
621
+
622
+ /**
623
+ * Displays success slide.
624
+ *
625
+ */
626
+ function showSuccessSlide()
627
+ {
628
+ jQuery('#' + workflow_vars.workflow_id+ '-failure').hide();
629
+ jQuery('#' + workflow_vars.workflow_id+ '-first').hide();
630
+ }
631
+
632
+ jQuery(no + ',' + no_request).on('click', function() {
633
+ Workflow.modals.close_modal('TB_closeWindowButton');
634
  });
635
 
636
+
637
+
638
+ function start_progress_bar()
639
+ {
640
+ jQuery('.loading-progress-percent').html(escape_html('0%'));
641
+ jQuery('.loading-progress-bar-inner').css('width', 0);
642
+ }
643
+
644
+ function update_progress_bar()
645
+ {
646
+ var finished = 0;
647
+ var total = 0;
648
+
649
+ for (var key in document_id_to_row_buffer)
650
+ {
651
+ if (Object.prototype.hasOwnProperty.call(document_id_to_row_buffer, key))
652
+ {
653
+ var val = document_id_to_row_buffer[key];
654
+ if (val)
655
+ {
656
+ finished++;
657
+ }
658
+ total++;
659
+ }
660
+ }
661
+ var percent = (finished / total) * 100;
662
+ jQuery('.loading-progress-percent').html(escape_html(parseInt(percent) + '%'));
663
+ jQuery('.loading-progress-bar-inner').css('width', percent + '%');
664
+ }
665
+
666
+ // /**
667
+ // * Launches a modal notifying the user of the chosen workflow.
668
+ // *
669
+ // * @param {any} event
670
+ // */
671
+ // function upload_handler(event)
672
+ // {
673
+ // event.preventDefault();
674
+ // Workflow.modals.stop_loading(workflow_vars.id);
675
+ // jQuery(this).addClass('thickbox');
676
+ // var url = Workflow.modals.replace_href(this);
677
+ // jQuery(yes).attr('href', url);
678
+ // jQuery(this).attr('href', '#TB_inline?width=800&height=300&inlineId=modal-window-id-' + workflow_vars.id);
679
+ // jQuery(yes).on('click', function() {
680
+ // Workflow.modals.loading(workflow_vars.id);
681
+ // });
682
+ // tb_show('<img src="' + workflow_vars.icon_url +'" style="padding-top:10px; display:inline-block"><span class="Upgrade-to-Lingotek header-professional">Upload Document To Lingotek</span>', '#TB_inline?width=800&height=300&inlineId=modal-window-id-' + workflow_vars.id);
683
+ // Workflow.modals.add_header_modal(workflow_vars.id);
684
+ // // tb_show('Upload Translation', '#TB_inline?width=500&height=300&inlineId=modal-window-id-' + workflow_vars.id);
685
+ // }
686
+
687
+
688
+
689
+ var click_bulk_action = false;
690
+
691
+ /**
692
+ * This is the event that is fired when a user clicks on the 'apply' button. It starts by checking that the option selected
693
+ * is the bulk request option. Then it goes through each of the valid post ids and checks if that row has been checked. If it has
694
+ * it looks to see if translation can be requested. If they can it pulls the essencial data off of the element and renders a row on the table.
695
+ *
696
+ * When a bulk action begins the start_bulk lock is enabled and doesn't allow subsequent requests to be processed until the modal is destroyed (closed)
697
+ * This prevents spam clicking errors.
698
+ *
699
+ * @param {event} event
700
+ * @returns
701
+ */
702
+ function bulk_request_handler(event)
703
+ {
704
+ if (jQuery('#bulk-action-selector-top').attr('value') === 'bulk-lingotek-request'
705
+ || jQuery('#bulk-action-selector-bottom').attr('value') === 'bulk-lingotek-request')
706
+ {
707
+
708
+ /**
709
+ * If a bulk action has already been initiated we want to abort this request.
710
+ */
711
+ if (start_bulk) { return; }
712
+ var ajax_request_made = false;
713
+
714
+ jQuery.each(item_ids.ids, function(item_id, valid_locales) {
715
+
716
+ var row_checked;
717
+ var row;
718
+ if (workflow_vars.curr_item_type === 'string')
719
+ {
720
+ row = get_string_group_row(item_id);
721
+ row_checked = jQuery('#string-select-' + item_id).prop('checked');
722
+ }
723
+ else
724
+ {
725
+ row = get_post_or_taxonomy_row(item_id);
726
+ row_checked = get_post_or_taxonomy_row(item_id).find('#cb-select-' + item_id).prop('checked');
727
+ }
728
+
729
+
730
+ if (row_checked) // If the row has been selected.
731
+ {
732
+ if (row_has_professional_translatable_items(row, item_id)) // If translations can be requested.
733
+ {
734
+ event.preventDefault();
735
+ /**
736
+ * Lock the operation.
737
+ */
738
+ start_bulk = true;
739
+ click_bulk_action = true;
740
+
741
+ /**
742
+ * Loading gif.
743
+ */
744
+ Workflow.modals.loading(workflow_vars.workflow_id+ '-request');
745
+ start_progress_bar();
746
+ var locale_list = [];
747
+ var locale_list_string = '';
748
+ var url = '';
749
+
750
+ /**
751
+ * We go through each 'requestable' locale and build a locale array and locale string.
752
+ */
753
+ row.find('.dashicons-plus-lingotek').each(function(index, element) {
754
+ url = (jQuery(element).attr('url')) ? jQuery(element).attr('url') : jQuery(element).attr('href');
755
+ var locale = Workflow.modals.get_url_parameter('locale', url);
756
+ if (is_valid_locale(locale, valid_locales))
757
+ {
758
+ Workflow.modals.replace_href(element);
759
+ var locale_code = workflow_vars.enabled_langs[locale].lingotek_locale;
760
+ if (jQuery.inArray(locale_code, locale_list) === -1)
761
+ {
762
+ locale_list_string += locale_code + ',';
763
+ locale_list.push(locale_code);
764
+ }
765
+ }
766
+ });
767
+
768
+ /**
769
+ * request
770
+ * If it's a valid url we render a row on the table.
771
+ */
772
+ if (url && url.length > 0)
773
+ {
774
+ /**
775
+ * Unlock the ajaxStop listener.
776
+ */
777
+ ajax_request_made = true;
778
+ var doc_id = Workflow.modals.get_url_parameter('document_id', url);
779
+ add_to_row_buffer(doc_id, locale_list_string, false, locale_list, true);
780
+ }
781
+
782
+
783
+ }
784
+ }
785
+ if (workflow_vars.curr_item_type === 'string')
786
+ {
787
+ jQuery('#string-select-' + item_id).prop('checked', false);
788
+ }
789
+ else
790
+ {
791
+ get_post_or_taxonomy_row(item_id).find('#cb-select-' + item_id).prop('checked', false);
792
+ }
793
+ });
794
+
795
+ /**
796
+ * This ensures that the ajaxStop event is enabled only if an ajax request has been made. Otherwise the events will
797
+ * pile up and the modal will be really slow when updating itself.
798
+ */
799
+ if (ajax_request_made)
800
+ {
801
+ set_payment_information();
802
+ jQuery(document).ajaxStop(function() {
803
+
804
+ /**
805
+ * This checks if ajax calls have been aborted. If they have this event will still fire because technically ajaxRequests have stopped
806
+ * but we don't want to attach any listeners or render anything if the modal has been closed.
807
+ */
808
+ if (abort_ajax) { return; }
809
+ try
810
+ {
811
+ render_rows_from_buffer();
812
+ var glob_list_copy = global_locale_list.slice(0);
813
+ render_table_headers(false, glob_list_copy, true);
814
+
815
+ console.log('ajax stop');
816
+
817
+ /**
818
+ * Hides the loading gif and shows everything but the hidden items on the table.
819
+ */
820
+ Workflow.modals.stop_loading(workflow_vars.workflow_id+ '-request', loading_exceptions);
821
+ init_table();
822
+ }
823
+ catch (err)
824
+ {
825
+ Workflow.modals.stop_loading(workflow_vars.workflow_id+ '-request', loading_exceptions);
826
+ show_error_screen();
827
+ show_loading_error();
828
+ }
829
+ jQuery(document).off('ajaxStop');
830
+ });
831
+ }
832
+ }
833
+ }
834
+
835
+ function row_has_professional_translatable_items(jQueryObjectRow, item_id)
836
+ {
837
+ var has_translatable_items = false;
838
+ jQueryObjectRow.find('.dashicons-plus-lingotek').each(function(index, element) {
839
+ var url = jQuery(element).attr('url');
840
+ var locale = Workflow.modals.get_url_parameter('locale', url);
841
+ if (is_valid_locale(locale, item_ids.ids[item_id]))
842
+ {
843
+ has_translatable_items = true;
844
+ }
845
+ });
846
+ return has_translatable_items;
847
+ }
848
+
849
+
850
+ function bulk_upload_handler(event)
851
+ {
852
+ if (jQuery('#bulk-action-selector-top').attr('value') === 'bulk-lingotek-upload'
853
+ || jQuery('#bulk-action-selector-bottom').attr('value') === 'bulk-lingotek-upload')
854
+ {
855
+ jQuery.each(item_ids.ids, function(id, lang) {
856
+ if (jQuery('#post-' + id + ', #tag-' + id).find('#cb-select-' + id).prop('checked'))
857
+ {
858
+ if (jQuery('#post-' + id + ', #tag-' + id).find('.dashicons-download-lingotek, .lingotek-professional-icon').length > 0)
859
+ {
860
+ jQuery('#post-' + id + ', #tag-' + id).find('#cb-select-' + id).prop('checked', false);
861
+ }
862
+ }
863
+ });
864
+ }
865
+ }
866
+
867
+
868
+
869
+ /**
870
+ * This method renders all rows that are in the buffer.
871
+ * The buffer is cleared everytime the modal is closed.
872
+ *
873
+ */
874
+ function render_rows_from_buffer()
875
+ {
876
+ jQuery.each(document_id_to_row_buffer, function(doc_id, object) {
877
+ if (object)
878
+ {
879
+ render_table_row(object.response, object.specific_locale, object.locale_list, object.response.data.document_id, object.check_all);
880
+ }
881
+ });
882
+ }
883
+
884
+ function set_payment_information()
885
+ {
886
+ var ajax_url = Workflow.modals.get_ajax_url('get_user_payment_information');
887
+
888
+ var request = Workflow.modals.ajax_request('GET', ajax_url, {'_lingotek_nonce' : workflow_vars.nonce}, function(response) {
889
+ console.log(response);
890
+ if (response.payment_info && response.payment_info.payment_profile)
891
+ {
892
+ show_does_have_payment_info(response);
893
+ }
894
+ else
895
+ {
896
+ show_doesnt_have_payment_info();
897
+ }
898
+ // set up stuff here
899
+ global_ajax_requests_list.splice(global_ajax_requests_list.indexOf(request), 1);
900
+ });
901
+
902
+ global_ajax_requests_list.push(request);
903
+ }
904
+
905
+ function show_does_have_payment_info(response)
906
+ {
907
+ jQuery('.payment-not-setup').hide();
908
+ jQuery('.payment-method-setup').show();
909
+ // jQuery('#blue-radio-button').attr('src', workflow_vars.blue_radio_button_url);
910
+ // jQuery('#credit-card-dots').attr('src', workflow_vars.credit_dots_url);
911
+ jQuery('#last-four-digits').html(escape_html( response.payment_info.payment_profile.cc.split('X').join('') ));
912
+ jQuery('#credit-card-image').attr('src', get_cc_type_asset_url(response.payment_info.payment_profile.cc_type));
913
+ jQuery('.header-professional').html(escape_html( 'Lingotek Professional Translation Services' ));
914
+ }
915
+
916
+ function get_cc_type_asset_url(cc_type)
917
+ {
918
+ return workflow_vars.cc_type_map[ cc_type ]
919
+ ? workflow_vars.cc_type_map[ cc_type ]
920
+ : workflow_vars.cc_type_map[ workflow_vars.default_cc_type ];
921
+ }
922
+
923
+ function show_doesnt_have_payment_info()
924
+ {
925
+ jQuery('.payment-not-setup').show();
926
+ jQuery('.payment-method-setup').hide();
927
+ jQuery('.header-professional').html(escape_html( 'Lingotek Professional Translation Quote Calculator' ));
928
+ }
929
+
930
+ function payment_portal_loading_screen()
931
+ {
932
+ jQuery('#TB_ajaxContent').find('*').not('.payment-portal-element').hide();
933
+ jQuery('.payment-portal-element').show();
934
+ }
935
+
936
+ function payment_portal_loading_screen_off()
937
+ {
938
+ jQuery('#TB_ajaxContent').find('*').not('.payment-portal-element').hide();
939
+ jQuery('.payment-portal-element').show();
940
+ }
941
+
942
+
943
+ /**
944
+ * This function is shared between the bulk request and single request user actions. It requires a document_id
945
+ * to send to bridge to get info about it. It also requires a comma separated string with the locales it would like to know about as far
946
+ * as cost goes, finally it takes in a locale list of locales that have been enabled for that row (profile)
947
+ *
948
+ * @param {string} document_id
949
+ * @param {string} comma_separated_locales
950
+ * @param {array} locale_list
951
+ * @param {boolean} [check_all=false]
952
+ */
953
+ function add_to_row_buffer(document_id, comma_separated_locales, specific_locale, locale_list, check_all = false)
954
+ {
955
+ document_id_to_row_buffer[document_id] = false;
956
+
957
+ var estimate_body = {
958
+ 'document_id' : document_id,
959
+ 'locale' : comma_separated_locales,
960
+ '_lingotek_nonce' : workflow_vars.nonce
961
+ };
962
+
963
+ console.log(estimate_body);
964
+ var estimate_ajax_url = Workflow.modals.get_ajax_url('estimate_cost');
965
+
966
+ /**
967
+ * We store the ajax_request in a list as they are sent off. When they return they remove themselves from the list after they complete their execution.
968
+ * We do this because if there are left over ajax requests after the modal is closed we don't want them manipulating the modal. All left over ajax requests
969
+ * are aborted as the modal is closed.
970
+ */
971
+ var request = Workflow.modals.ajax_request('GET', estimate_ajax_url, estimate_body, function(response) {
972
+ console.log(response);
973
+
974
+ document_id_to_row_buffer[response.data.document_id] = {
975
+ 'response' : response,
976
+ 'specific_locale' : specific_locale,
977
+ 'locale_list' : locale_list,
978
+ 'check_all' : check_all
979
+ };
980
+ global_ajax_requests_list.splice(global_ajax_requests_list.indexOf(request), 1);
981
+ update_progress_bar();
982
+ });
983
+ global_ajax_requests_list.push(request);
984
+ }
985
+
986
+
987
+ /**
988
+ * Launches the modal that displays the cost of a single document. Allows the user to request translation.
989
+ *
990
+ * @param {any} event
991
+ */
992
+ function request_handler(event)
993
+ {
994
  event.preventDefault();
995
+
996
+ // var _this = this;
997
  var url = Workflow.modals.replace_href(this);
998
+ // var doc_id = Workflow.modals.get_url_parameter('document_id', url);
 
 
999
 
1000
+ /**
1001
+ * We store the clicked locale because we want to display this first in the list so that the user doesn't have to click in order
1002
+ * to see that it is selected.
1003
+ */
1004
+ var clicked_locale_code = workflow_vars.enabled_langs[Workflow.modals.get_url_parameter('locale', url)].lingotek_locale;
1005
+
1006
+ render_post_row(this, clicked_locale_code);
1007
+ }
1008
+
1009
+ /**
1010
+ * When the Request translation row action is selected the render_post_method_with_locales method is delegated
1011
+ * with the options to:
1012
+ * 1. Not care about any specific row ordering.
1013
+ * 2. Check all of the header boxes.
1014
+ * 3. Check all of the row boxes.
1015
+ *
1016
+ * @param {event} event
1017
+ */
1018
+ function request_translation_row_handler(event)
1019
+ {
1020
+ event.preventDefault();
1021
+ render_post_row(jQuery(this).children()[0], false, true, true);
1022
+ }
1023
+
1024
+ /**
1025
+ * This method renders a table with a single row. This is used for requesting a single translation and requesting translations
1026
+ * for an entire row. It requires the caller to pass in the element that contains the url. It requires the user to specify whether
1027
+ * there is a specific locale ordering. It allows the caller to decide whether all headers and / or all rows should be checked.
1028
+ *
1029
+ * @param {object} element
1030
+ * @param {string || boolean} clicked_locale_code
1031
+ * @param {boolean} [check_all_headers=false]
1032
+ * @param {boolean} [check_all_rows=false]
1033
+ */
1034
+ function render_post_row(element, clicked_locale_code, check_all_headers = false, check_all_rows = false)
1035
+ {
1036
+ var url = Workflow.modals.replace_href(element);
1037
+ var doc_id = Workflow.modals.get_url_parameter('document_id', url);
1038
+
1039
+ var locale_data = get_row_locale_data(jQuery(element), clicked_locale_code);
1040
+ /**
1041
+ * Attach out listeners.
1042
+ */
1043
+
1044
+ Workflow.modals.loading(workflow_vars.workflow_id+ '-request');
1045
+ start_progress_bar();
1046
+
1047
+ /**
1048
+ * The parameters we pass to the render table row method indicates that we care about which item is displayed first and that
1049
+ * we DON'T want every box checked.
1050
+ */
1051
+ add_to_row_buffer(doc_id, locale_data.csv, clicked_locale_code, locale_data.locale_list, check_all_rows);
1052
+ set_payment_information();
1053
+ jQuery(document).ajaxStop(function() {
1054
+ console.log('ajax stop in');
1055
+ try
1056
+ {
1057
+ render_rows_from_buffer();
1058
+
1059
+ /**
1060
+ * Again, this method call indicates that we want the clicked locale to be displayed first in the header.
1061
+ */
1062
+ var glob_list_copy = global_locale_list.slice(0);
1063
+ render_table_headers(clicked_locale_code, glob_list_copy, check_all_headers);
1064
+ Workflow.modals.stop_loading(workflow_vars.workflow_id+ '-request', loading_exceptions);
1065
+
1066
+
1067
+ init_table();
1068
+ }
1069
+ catch(err)
1070
+ {
1071
+ Workflow.modals.stop_loading(workflow_vars.workflow_id+ '-request', loading_exceptions);
1072
+ show_error_screen();
1073
+ show_loading_error();
1074
+ }
1075
+
1076
+ jQuery(document).off('ajaxStop');
1077
+ });
1078
+ }
1079
+
1080
+ /**
1081
+ * This method is used to find all of the locales on a given row. Because we want to grab all of the valid locales on a given
1082
+ * row we need to go up a few levels until we find the current row ('tr'), then we can find all of the .dashicons-plus elements
1083
+ * and extract their locale codes from their hrefs.
1084
+ *
1085
+ * @param {object} jQueryObject
1086
+ * @param {string} clicked_locale_code
1087
+ * @returns
1088
+ */
1089
+ function get_row_locale_data(jQueryObject, clicked_locale_code)
1090
+ {
1091
+ var locale_list = [];
1092
+ var comma_separated_locales = '';
1093
+ if (clicked_locale_code)
1094
+ {
1095
+ comma_separated_locales += clicked_locale_code + ',';
1096
+ locale_list.push(clicked_locale_code);
1097
+ }
1098
+ var item_id = get_row_item_id(jQueryObject);
1099
+ jQueryObject.closest('tr').find('.dashicons-plus').each(function(index, elem) {
1100
+ var url = jQuery(elem).attr('url');
1101
+ var locale = Workflow.modals.get_url_parameter('locale', url);
1102
+ if (is_valid_locale(locale, item_ids.ids[item_id]))
1103
+ {
1104
+ Workflow.modals.replace_href(elem);
1105
+ var locale_code = workflow_vars.enabled_langs[locale].lingotek_locale;
1106
+ if (clicked_locale_code !== locale_code)
1107
+ {
1108
+ comma_separated_locales += locale_code + ',';
1109
+ locale_list.push(locale_code);
1110
+ }
1111
+ }
1112
+ });
1113
+
1114
+ return {
1115
+ 'csv' : comma_separated_locales,
1116
+ 'locale_list' : locale_list
1117
+ };
1118
+ }
1119
+
1120
+ function get_row_item_id(jQueryObject)
1121
+ {
1122
+ if (workflow_vars.curr_item_type === 'string')
1123
+ {
1124
+ return jQueryObject.closest('tr').find('input[id*="string-select-"]').attr('id').split('-')[2];
1125
+ }
1126
+ else
1127
+ {
1128
+ return jQueryObject.closest('tr').attr('id').split('-')[1];;
1129
+ }
1130
+ }
1131
+
1132
+ function close()
1133
+ {
1134
  Workflow.modals.close_modal('TB_closeWindowButton');
1135
+ }
1136
+
1137
+ function init_table()
1138
+ {
1139
+ terms_and_conditions_listener();
1140
+ accept_terms_and_conditions_listener();
1141
+ buy_now_listener();
1142
+ listen_for_language_cycle_click();
1143
+ attach_row_total_listeners();
1144
+ attach_table_change_listener();
1145
+ attach_header_listeners();
1146
+ update_table();
1147
+ update_row_totals();
1148
+ hide_terms_and_conditions();
1149
+ set_up_side_panel_height();
1150
+ }
1151
+
1152
+ var document_id_list = [];
1153
+ var active_locale_list = [];
1154
+
1155
+ /**
1156
+ * This value indicates how many columns will be shown on the table at one time.
1157
+ */
1158
+ var table_element_limit = 3;
1159
+
1160
+ /**
1161
+ * These two variables are how we track what has already been shown on the modal. When a header or column has
1162
+ * been displayed on the modal it is added to this list. After all headers and columns have been shown or the modal is destroyed
1163
+ * these lists is clear.
1164
+ */
1165
+ var shown_headers = [];
1166
+ var shown_columns = {};
1167
+
1168
+ /**
1169
+ * This attaches an event listener to the button that allows users to click through different languages.
1170
+ *
1171
+ */
1172
+ function listen_for_language_cycle_click()
1173
+ {
1174
+ if (can_cycle_langauges())
1175
+ {
1176
+ remove_extra_columns();
1177
+ jQuery('#next-language-set').on('click', function() {
1178
+ remove_extra_columns();
1179
+ cycle_through_headers();
1180
+ jQuery.each(document_id_list, function(index, value) {
1181
+ cycle_through_columns(value);
1182
+ });
1183
+ });
1184
+ }
1185
+ else
1186
+ {
1187
+ jQuery('#next-language-set').hide();
1188
+ }
1189
+ }
1190
+
1191
+ /**
1192
+ * Columns are added as padding for when the number of columns left to display (the ones that haven't been shown yet) is
1193
+ * less than the number of elements that are meant to be shown after each click. These extra columns are removed after the button
1194
+ * is clicked.
1195
+ */
1196
+ function remove_extra_columns()
1197
+ {
1198
+ jQuery('.extra-column').remove();
1199
+ }
1200
+
1201
+ /**
1202
+ * Extra padding columns are added to the table if there aren't enough elements left to show on the current view of the modal.
1203
+ *
1204
+ * For example: If the user has 5 languages enabled and the modal is currently only displaying 3, when the user clicks on the 'more' button
1205
+ * to see the rest of their languages there will only be two left to show. To avoid the table changing column length and moving things around annoyingly
1206
+ * an extra column is added as padding.
1207
+ *
1208
+ * @param {object} jQueryObject
1209
+ */
1210
+ function add_extra_columns(jQueryObject)
1211
+ {
1212
+ if (jQueryObject.length < table_element_limit)
1213
+ {
1214
+ var extra_columns = table_element_limit - jQueryObject.length;
1215
+ for (var i = 0; i < extra_columns; i++)
1216
+ jQueryObject.last().after(jQuery.parseHTML("<td class='extra-column'></td>"));
1217
+ }
1218
+ }
1219
+
1220
+ /**
1221
+ * This is the method responsible for hiding and showing different columns in order to allow the user to 'click' through their enabled languages.
1222
+ * It takes in a document_id and finds the row associated with that id. Then it goes through each entry in that row and determines whether to hide it or show it.
1223
+ * It is important to note that there is a global list that maps document ids to table elements in order to keep track of which items have already been
1224
+ * shown to the user. This method only acts on one row at a time.
1225
+ *
1226
+ * @param {string} document_id
1227
+ */
1228
+ function cycle_through_columns(document_id)
1229
+ {
1230
+ var counter = 0;
1231
+ jQuery('.' + document_id + '-row-table').each(function(index, val) {
1232
+ if (! jQuery(val).hasClass('row-table-hidden'))
1233
+ {
1234
+ jQuery(val).addClass('row-table-hidden');
1235
+ }
1236
+ else if (jQuery(val).hasClass('row-table-hidden'))
1237
+ {
1238
+ if (counter < table_element_limit && jQuery.inArray(val, shown_columns[document_id]) === -1)
1239
+ {
1240
+ jQuery(val).removeClass('row-table-hidden');
1241
+ shown_columns[document_id].push(val);
1242
+ counter++;
1243
+ }
1244
+ }
1245
+ });
1246
+ if (jQuery('.' + document_id + '-row-table').length <= shown_columns[document_id].length)
1247
+ {
1248
+ shown_columns[document_id] = [];
1249
+ }
1250
+
1251
+ add_extra_columns(jQuery('.' + document_id + '-row-table').not('.row-table-hidden'));
1252
+ }
1253
+
1254
+ /**
1255
+ * This method is responsible for shuffling through the headers (language names) as the user clicks
1256
+ * through the table. Like the cycle_though_columns() method there is a global list keeping track of which
1257
+ * headers have already been seen.
1258
+ *
1259
+ */
1260
+ function cycle_through_headers()
1261
+ {
1262
+ var counter = 0;
1263
+ jQuery('.header-table, .header-table-hidden').each(function(index, val) {
1264
+ if (jQuery(val).hasClass('header-table'))
1265
+ {
1266
+ jQuery(val).removeClass('header-table').addClass('header-table-hidden');
1267
+ }
1268
+ else if (jQuery(val).hasClass('header-table-hidden'))
1269
+ {
1270
+ if (counter < table_element_limit && jQuery.inArray(val, shown_headers) === -1)
1271
+ {
1272
+ jQuery(val).removeClass('header-table-hidden').addClass('header-table');
1273
+ shown_headers.push(val);
1274
+ counter++;
1275
+ }
1276
+ }
1277
+ });
1278
+ if (jQuery('.header-table, .header-table-hidden').length <= shown_headers.length)
1279
+ {
1280
+ shown_headers = [];
1281
+ }
1282
+
1283
+ add_extra_columns(jQuery('.header-table'));
1284
+ }
1285
+
1286
+ function can_cycle_langauges()
1287
+ {
1288
+ return jQuery('.header-table, .header-table-hidden').length > table_element_limit;
1289
+ }
1290
+
1291
+
1292
+ /**
1293
+ * This is the method that renders the table in the modal. It embeds a bit of tracking information into each html element
1294
+ * in order to keep track of clicks in order to update the 'total' fields on the table dynamically.
1295
+ *
1296
+ * @param {obj} response
1297
+ * @param {string} locale
1298
+ * @param {array} locales
1299
+ * @param {string} document_id
1300
+ *
1301
+ */
1302
+ function render_table_row(response, specific_locale_code, locales, document_id, check_all_on_row = false)
1303
+ {
1304
+ if (!response.success) throw response;
1305
+
1306
+ if (jQuery.inArray(document_id, document_id_list) === -1) { document_id_list.push(document_id); } // keep track of our document ids.
1307
+
1308
+ var glob_locale_copy = global_locale_list.slice(0);
1309
+
1310
+ var element = "<tr class='bordered-bottom request-table-item'><td class='document-title' title='"+ escape_html(response.data.document_title) +"'>"+ escape_html(response.data.document_title) +"</td><td class='word-count words-"+ escape_html(document_id) +"'>"+ escape_html(response.data.word_count) +"</td>";
1311
+ var row_total = 0;
1312
+ var counter = 0;
1313
+ var iteration_length = global_locale_list.length;
1314
+
1315
+ /**
1316
+ * This method supports rendering a row starting with a certain locale code. If that variable has been set then we will use it to render the first row.
1317
+ */
1318
+ if (specific_locale_code)
1319
+ {
1320
+ element += "<td class='"+ escape_html(document_id) +"-row-table cost-font-size'><input class='"+ escape_html(specific_locale_code) +" checkable "+ escape_html(document_id) +"' type='checkbox' name='confirm-request' value='"+ escape_html(response.data.costs[specific_locale_code].estimated_cost) +"'>$"+ escape_html(response.data.costs[specific_locale_code].estimated_cost) +"</td>";
1321
+ glob_locale_copy.splice(glob_locale_copy.indexOf(specific_locale_code), 1);
1322
+ counter = 1;
1323
+ row_total = parseFloat(response.data.costs[specific_locale_code].estimated_cost.replace(',', ''));
1324
+ iteration_length--;
1325
+ }
1326
+
1327
+
1328
+ for (var i = 0; i < iteration_length; i++)
1329
+ {
1330
+ var next_local = get_next_locale(glob_locale_copy);
1331
+ var display_class = '';
1332
+
1333
+ /**
1334
+ * If we are already showing the max number of columns we will still render the rest of the columns but we will hide them.
1335
+ */
1336
+ if (counter >= table_element_limit) { display_class = 'row-table-hidden'; }
1337
+
1338
+ /**
1339
+ * The next_locale variable is coming from our global list of locales. We are checking to see if that locale is contained in the locales list that was
1340
+ * passed into the method. The locale list passed into the method contains the languages that have been enabled for this particular document.
1341
+ * If the next_locale variable is not found in our enabled locales list then we add a row that doesn't contain any sort of input.
1342
+ */
1343
+ if (next_local && jQuery.inArray(next_local, locales) !== -1)
1344
+ {
1345
+ element += "<td class='"+ escape_html(document_id) +"-row-table cost-font-size "+ escape_html(display_class) +"'><input class='"+ escape_html(next_local) +" checkable "+ escape_html(document_id) +"' type='checkbox' name='confirm-request' value='"+ escape_html(response.data.costs[next_local].estimated_cost) +"'>$"+ escape_html(response.data.costs[next_local].estimated_cost) +"</td>"
1346
+ }
1347
+ else
1348
+ {
1349
+ element += "<td class='"+ escape_html(document_id) +"-row-table cost-font-size "+ escape_html(display_class) +"'><span ltk-data-tooltip-ctr='This element is unavailable for translation ...'><input type='checkbox' disabled></span></td>";
1350
+ }
1351
+ counter++;
1352
+ }
1353
+ element += "<td></td><td class='invisible row-total-" + escape_html(document_id) + " row-total'>$"+ escape_html(row_total.toFixed(2)) +"</td></tr>"; // Add the row total.
1354
+
1355
+ jQuery('.request-table > tbody').append(jQuery.parseHTML(element)); // Add the element to our document.
1356
+
1357
+ /**
1358
+ * This method supports the option to check all of the items on this particular row.
1359
+ */
1360
+ if (check_all_on_row)
1361
+ {
1362
+ jQuery('.' + document_id).prop('checked', true);
1363
+ }
1364
+
1365
+ /**
1366
+ * If a specific locale code is passed in then that row and header is checked.
1367
+ */
1368
+ if (specific_locale_code)
1369
+ {
1370
+ jQuery('.' + specific_locale_code + ', .' + specific_locale_code + '-header').prop('checked', true);
1371
+ }
1372
+
1373
+
1374
+ /**
1375
+ * Here we keep track of which comments are being shown so that we don't show them again until all columns have been seen at least once.
1376
+ */
1377
+ shown_columns[document_id] = [];
1378
+ jQuery('.' + document_id + '-row-table').not('.row-table-hidden').each(function(index, value) {
1379
+ shown_columns[document_id].push(value);
1380
+ });
1381
+ }
1382
+
1383
+ /**
1384
+ * Renders the table header.
1385
+ *
1386
+ * @param {string} locale_code
1387
+ * @param {array} locales
1388
+ */
1389
+ function render_table_headers(specific_locale_code, locales, check_all_headers = false)
1390
+ {
1391
+ var header = '';
1392
+ var counter = 0;
1393
+
1394
+ /**
1395
+ * This method - like render_table_row - supports the option to start the header with a specific locale.
1396
+ */
1397
+ if (specific_locale_code)
1398
+ {
1399
+ locales.splice(locales.indexOf(specific_locale_code), 1);
1400
+ header += "<th class='appended header-table' title='"+ escape_html(get_language_from_locale(specific_locale_code)) +" ("+ escape_html(get_country_from_locale(specific_locale_code)) +")'><div class='document-title language-header'>"+escape_html(get_language_from_locale(specific_locale_code))+" ("+escape_html(get_country_from_locale(specific_locale_code))+")</div><input class='"+ escape_html(specific_locale_code) +"-header' type='checkbox' name='confirm-request' value='request-translation'><span class='"+escape_html(specific_locale_code)+"-header-cost cost-header'>" + escape_html('$40.99') + "</span></th>";
1401
+ counter = 1;
1402
+ }
1403
+
1404
+ var next_local;
1405
+ while (next_local = get_next_locale(locales))
1406
+ {
1407
+ var display_class = '';
1408
+ if (counter >= table_element_limit) { display_class = '-hidden'; }
1409
+ header += "<th class='appended header-table"+ escape_html(display_class) +"' title='"+ escape_html(get_language_from_locale(next_local)) +" ("+ escape_html(get_country_from_locale(next_local)) +")'><div class='document-title language-header'>"+escape_html(get_language_from_locale(next_local))+" ("+escape_html(get_country_from_locale(next_local))+")</div><input class='"+ escape_html(next_local) +"-header' type='checkbox' name='confirm-request' value='request-translation'><span class='"+escape_html(next_local)+"-header-cost cost-header'>" + escape_html('$40.99') + "</span></th>";
1410
+ counter++;
1411
+ }
1412
+
1413
+ /**
1414
+ * Any left over appended columns are removed. This prevents left over data from being present on the modal after it is closed.
1415
+ */
1416
+ jQuery('.appended').remove();
1417
+
1418
+
1419
+ jQuery('#words-column').after(jQuery.parseHTML(header));
1420
+
1421
+ /**
1422
+ * This method supports the option to mark all of the headers as checked.
1423
+ */
1424
+ if (check_all_headers)
1425
+ {
1426
+ jQuery.each(global_locale_list, function(index, value) {
1427
+ if (jQuery('.' + value).length > 0)
1428
+ jQuery('.' + value + '-header').prop('checked', true);
1429
+ });
1430
+ }
1431
+
1432
+ /**
1433
+ * Check the header if a specific locale was passed in.
1434
+ */
1435
+ if (specific_locale_code)
1436
+ {
1437
+ jQuery('.' + specific_locale_code + '-header').prop('checked', true);
1438
+ }
1439
+
1440
+ /**
1441
+ * Keeping track of which headers are currently being shown.
1442
+ */
1443
+ jQuery('.header-table').each(function(index, value) {
1444
+ shown_headers.push(value);
1445
+ });
1446
+ }
1447
+
1448
+ /**
1449
+ * Sets the checked property of a given element.
1450
+ *
1451
+ * @param {string} element_class
1452
+ * @param {boolean} isChecked
1453
+ */
1454
+ function set_input_check(element_class, isChecked)
1455
+ {
1456
+ jQuery(element_class).prop('checked', isChecked);
1457
+ }
1458
+
1459
+ /**
1460
+ * Attaches click listeners to the headers of the table. When the header checkboxes are
1461
+ * clicked, the table is updated.
1462
+ *
1463
+ */
1464
+ function attach_header_listeners()
1465
+ {
1466
+ jQuery.each(global_locale_list, function(index,value) {
1467
+ jQuery(document).on('click', '.' + value + '-header', function() {
1468
+ set_input_check('.' + value, jQuery('.' + value + '-header').prop('checked'));
1469
+ update_table();
1470
+ update_row_totals();
1471
+ });
1472
+ });
1473
+ }
1474
+
1475
+ /**
1476
+ * Updates the row total amount when an element is clicked.
1477
+ *
1478
+ */
1479
+ function attach_row_total_listeners()
1480
+ {
1481
+ // TODO: optimize row listener
1482
+ jQuery.each(document_id_list, function(index,value) {
1483
+ jQuery(document).on('click', '.' + value, function() {
1484
+ console.log('total');
1485
+ update_row_total(value);
1486
+ })
1487
+ });
1488
+ }
1489
+
1490
+ /**
1491
+ * Updates a row total amount based on boxes that have been checked.
1492
+ *
1493
+ * @param {string} document_id
1494
+ */
1495
+ function update_row_total(document_id)
1496
+ {
1497
+ var total = 0.0;
1498
+ jQuery('.' + document_id + ':checked').each(function(key, item) {
1499
+ total += parseFloat(jQuery(item).attr('value').replace(',', ''));
1500
+ });
1501
+ jQuery('.row-total-' + document_id).html(escape_html( '$' + total.toFixed(2) ));
1502
+ }
1503
+
1504
+ /**
1505
+ * Updates all row totals.
1506
+ *
1507
+ */
1508
+ function update_row_totals()
1509
+ {
1510
+ jQuery.each(document_id_list, function(index, value) {
1511
+ update_row_total(value);
1512
+ });
1513
+ }
1514
+
1515
+ /**
1516
+ * Updates the word count on the modal.
1517
+ *
1518
+ */
1519
+ // function update_word_count()
1520
+ // {
1521
+ // var total = 0.0;
1522
+ // jQuery.each(document_id_list, function(index,value) {
1523
+ // var multiplier = jQuery('.' + value + ':checked').length;
1524
+ // var doc_word_count = parseInt(jQuery('.words-' + value).html());
1525
+ // total += multiplier * doc_word_count;
1526
+ // });
1527
+ // var word_string = total === 1 ? ' Word Translated' : ' Words Translated';
1528
+ // jQuery('#number-of-words').html(escape_html( total + word_string ));
1529
+ // }
1530
+
1531
+ /**
1532
+ * Updates the page count on the modal.
1533
+ *
1534
+ */
1535
+ // function update_page_count()
1536
+ // {
1537
+ // var page_number = 0;
1538
+ // jQuery.each(document_id_list, function(index,value) {
1539
+ // if (jQuery('.' + value + ':checked').length > 0)
1540
+ // {
1541
+ // ++page_number;
1542
+ // }
1543
+ // });
1544
+ // var page_string = page_number === 1 ? ' Post' : ' Posts';
1545
+ // jQuery('#number-of-pages').html(escape_html( page_number + page_string ));
1546
+ // }
1547
+
1548
+ /**
1549
+ * Updates the table when a 'checkable' element has been checked.
1550
+ *
1551
+ */
1552
+ function attach_table_change_listener()
1553
+ {
1554
+ jQuery(document).on('click', '.checkable', function() {
1555
+ if (! jQuery(this).prop('checked'))
1556
+ {
1557
+ var locale_code = get_item_from_class(jQuery(this).attr('class'), global_locale_list);
1558
+ set_input_check('.' + locale_code + '-header', false);
1559
+ }
1560
+ update_table();
1561
+ })
1562
+ }
1563
+
1564
+ /**
1565
+ * Retrieves the locale code from an element class.
1566
+ *
1567
+ * @param {string} class_string
1568
+ * @returns
1569
+ */
1570
+ function get_item_from_class(class_string, list)
1571
+ {
1572
+ var arr = class_string.split(' ');
1573
+ for (var i = 0; i < arr.length; i++)
1574
+ {
1575
+ var value = arr[i];
1576
+ if (jQuery.inArray(value, list) !== -1)
1577
+ {
1578
+ return value;
1579
+ }
1580
+ }
1581
+ }
1582
+
1583
+ /**
1584
+ * Updates the total cost element based on which boxes have been checked.
1585
+ */
1586
+ function update_total_cost()
1587
+ {
1588
+ var total_cost = 0.00;
1589
+ jQuery.each(workflow_vars.enabled_langs, function(index, item) {
1590
+ total_cost += get_cost_by_locale(item.lingotek_locale, false);
1591
+ });
1592
+ jQuery('.lingotek-total-amount').html(escape_html( '$' + number_with_commas(total_cost.toFixed(2))));
1593
+ }
1594
+
1595
+ /**
1596
+ * Updates the "Translated into: " {list of languages} portion of the modal.
1597
+ *
1598
+ */
1599
+ // function update_translated_into()
1600
+ // {
1601
+ // var locale_list = [];
1602
+ // var translated_into = '';
1603
+ // jQuery('.checkable:checked').each(function(key, item) {
1604
+ // var locale_code = get_item_from_class(jQuery(item).attr('class'), global_locale_list);
1605
+ // if (jQuery.inArray(locale_code, locale_list) === -1)
1606
+ // {
1607
+ // locale_list.push(locale_code);
1608
+ // translated_into += get_language_from_locale(locale_code) + ', ';
1609
+ // }
1610
+ // });
1611
+
1612
+ // var string = '';
1613
+ // if (locale_list.length > 0)
1614
+ // {
1615
+ // string = 'Translated into: ' + translated_into.slice(0,-2) + '.';
1616
+ // }
1617
+ // else
1618
+ // {
1619
+ // string = 'No translations selected!'
1620
+ // }
1621
+ // jQuery('#translated-into').html(escape_html( string ));
1622
+ // }
1623
+
1624
+ function update_request_summary()
1625
+ {
1626
+ jQuery('.translation-summary-list-ltk').empty();
1627
+ var list = get_request_summary_list();
1628
+ jQuery.each(list, function(index, item) {
1629
+ var css_class = get_cost_by_locale(item.locale) < MINIMUM ? 'minimum-warning' : '';
1630
+ var minimum_star = get_cost_by_locale(item.locale) < MINIMUM ? '*' : '';
1631
+ var element = "<li><span class='translation-summary-list-text translation-summary-list-text-ltk'>"+item.name + ': ' + item.count + ' words ' + "<span class='translation-summary-cost "+css_class+"'>$"+ number_with_commas(item.cost.toFixed(2)) + minimum_star +"</span></li>";
1632
+ jQuery('.translation-summary-list-ltk').append(element);
1633
+ });
1634
+ }
1635
+
1636
+ function get_request_summary_list()
1637
+ {
1638
+ var list = [];
1639
+ jQuery.each(workflow_vars.enabled_langs, function(index, item) {
1640
+ if (jQuery('.' + item.lingotek_locale + ':checked').length > 0)
1641
+ {
1642
+ list.push({
1643
+ 'locale' : item.lingotek_locale,
1644
+ 'name' : item.language + ', ' + item.country_name,
1645
+ 'count' : get_word_count_by_locale(item.lingotek_locale),
1646
+ 'cost' : get_cost_by_locale(item.lingotek_locale, false)
1647
+ });
1648
+ }
1649
+ });
1650
+
1651
+ return list;
1652
+ }
1653
+
1654
+ function get_word_count_by_locale(locale)
1655
+ {
1656
+ var word_count = 0;
1657
+ jQuery('.' + locale).each(function(index, item) {
1658
+ if (!jQuery(item).prop('checked')) { return; }
1659
+ var doc_id = get_item_from_class(jQuery(item).attr('class'), document_id_list);
1660
+ word_count += parseInt(jQuery('.words-' + doc_id).html());
1661
+ });
1662
+ return word_count;
1663
+ }
1664
+
1665
+ function get_cost_by_locale(locale, raw = true)
1666
+ {
1667
+ var cost = 0.0;
1668
+ jQuery('.' + locale).each(function(index, item) {
1669
+ if (jQuery(item).prop('checked'))
1670
+ {
1671
+ cost += parseFloat(jQuery(item).val().replace(/,/g, ''));
1672
+ }
1673
+ });
1674
+
1675
+ if (!raw && cost > 0.0)
1676
+ {
1677
+ cost = cost < MINIMUM ? MINIMUM : cost;
1678
+ }
1679
+ return cost;
1680
+ }
1681
+
1682
+ function update_estimated_delivery()
1683
+ {
1684
+ var max_word_count = 0;
1685
+ jQuery.each(workflow_vars.enabled_langs, function(index, item) {
1686
+ var word_count = get_word_count_by_locale(item.lingotek_locale);
1687
+ if (word_count > max_word_count) { max_word_count = word_count; }
1688
+ });
1689
+ var additional_days = parseInt(max_word_count / DELIVERY_WORDS_INCREASE);
1690
+ var min_delivery = DEFAULT_MINIMUM_DELIVERY_DAYS + additional_days;
1691
+ var max_delivery = DEFAULT_MAXIMUM_DELIVERY_DAYS + additional_days;
1692
+ jQuery('.business-days').html(min_delivery + ' - ' + max_delivery + ' business days.');
1693
+ }
1694
+
1695
+ function update_header_values()
1696
+ {
1697
+ jQuery.each(workflow_vars.enabled_langs, function(index, item) {
1698
+ var cost = get_cost_by_locale(item.lingotek_locale);
1699
+ var not_meeting_minimum = cost < MINIMUM && cost > 0;
1700
+ var html_cost = '$' + number_with_commas(cost.toFixed(2));
1701
+
1702
+ if (not_meeting_minimum)
1703
+ {
1704
+ html_cost += '*';
1705
+ }
1706
+
1707
+ jQuery('.' + item.lingotek_locale + '-header-cost').html(html_cost);
1708
+
1709
+ if (not_meeting_minimum)
1710
+ {
1711
+ jQuery('.' + item.lingotek_locale + '-header-cost').addClass('minimum-warning');
1712
+ }
1713
+ else
1714
+ {
1715
+ jQuery('.' + item.lingotek_locale + '-header-cost').removeClass('minimum-warning');
1716
+ }
1717
+ });
1718
+ }
1719
+
1720
+ function check_minimums()
1721
+ {
1722
+ var mins_met = true;
1723
+ jQuery.each(workflow_vars.enabled_langs, function(index, item) {
1724
+ var cost = get_cost_by_locale(item.lingotek_locale);
1725
+ mins_met = mins_met && (cost >= MINIMUM || cost === 0);
1726
+ });
1727
+ if (mins_met)
1728
+ {
1729
+ jQuery('.minimum-per-language-warning').hide();
1730
+ }
1731
+ else
1732
+ {
1733
+ jQuery('.minimum-per-language-warning').show();
1734
+ }
1735
+ }
1736
+
1737
+ /**
1738
+ * This method takes in a locale (one of the locales embedded into the icon href) and returns the english translated of that
1739
+ * langauge
1740
+ *
1741
+ * @param {string} locale
1742
+ * @returns
1743
+ */
1744
+ function get_language_from_locale(locale)
1745
+ {
1746
+ for (var key in workflow_vars.enabled_langs)
1747
+ {
1748
+ if (Object.prototype.hasOwnProperty.call(workflow_vars.enabled_langs, key))
1749
+ {
1750
+ var val = workflow_vars.enabled_langs[key];
1751
+ if (val.lingotek_locale === locale)
1752
+ {
1753
+ return val.language;
1754
+ }
1755
+ }
1756
+ }
1757
+ }
1758
+
1759
+ function get_country_from_locale(locale)
1760
+ {
1761
+ for (var key in workflow_vars.enabled_langs)
1762
+ {
1763
+ if (Object.prototype.hasOwnProperty.call(workflow_vars.enabled_langs, key))
1764
+ {
1765
+ var val = workflow_vars.enabled_langs[key];
1766
+ if (val.lingotek_locale === locale)
1767
+ {
1768
+ return val.country_name;
1769
+ }
1770
+ }
1771
+ }
1772
+ }
1773
+
1774
+ function get_wp_locale_from_lingotek_locale(locale)
1775
+ {
1776
+ for (var key in workflow_vars.enabled_langs)
1777
+ {
1778
+ if (Object.prototype.hasOwnProperty.call(workflow_vars.enabled_langs, key))
1779
+ {
1780
+ var val = workflow_vars.enabled_langs[key];
1781
+ if (val.lingotek_locale === locale)
1782
+ {
1783
+ return key;
1784
+ }
1785
+ }
1786
+ }
1787
+ }
1788
+
1789
+ function get_lingotek_locale_to_wp_locale_list()
1790
+ {
1791
+ var list = {};
1792
+ for (var key in workflow_vars.enabled_langs)
1793
+ {
1794
+ if (Object.prototype.hasOwnProperty.call(workflow_vars.enabled_langs, key))
1795
+ {
1796
+ var val = workflow_vars.enabled_langs[key];
1797
+ list[val.lingotek_locale] = key;
1798
+ }
1799
+ }
1800
+ return list;
1801
+ }
1802
+
1803
+ /**
1804
+ * Delegates this call to several updater methods.
1805
+ *
1806
+ */
1807
+ function update_table()
1808
+ {
1809
+ // update_word_count();
1810
+ update_total_cost();
1811
+ update_request_summary();
1812
+ update_estimated_delivery();
1813
+ update_header_values();
1814
+ check_minimums();
1815
+ // update_page_count();
1816
+ // update_translated_into();
1817
+ }
1818
+
1819
+ /**
1820
+ * Cycles through a list of locales and gives one back while removing it from the list.
1821
+ *
1822
+ * @param {array} locales
1823
+ * @returns
1824
+ */
1825
+ function get_next_locale(locales)
1826
+ {
1827
+ if (locales.length > 0)
1828
+ {
1829
+ var locale = locales[0];
1830
+ locales.splice(0,1);
1831
+ return locale;
1832
+ }
1833
+ else
1834
+ {
1835
+ return false;
1836
+ }
1837
+ }
1838
+
1839
+ var entityMap = {
1840
+ '&': '&amp;',
1841
+ '<': '&lt;',
1842
+ '>': '&gt;',
1843
+ '"': '&quot;',
1844
+ "'": '&#39;',
1845
+ '/': '&#x2F;',
1846
+ '`': '&#x60;',
1847
+ '=': '&#x3D;'
1848
+ };
1849
+
1850
+ function escape_html (string)
1851
+ {
1852
+ return String(string).replace(/[&<>"'`=\/]/g, function (s) {
1853
+ return entityMap[s];
1854
+ });
1855
+ }
1856
+
1857
+ function number_with_commas(x) {
1858
+ return x.toString().replace(/\B(?=(\d{3})+(?!\d))/g, ",");
1859
+ }
1860
+
1861
+ });
js/workflow/workflow-defaults.js DELETED
@@ -1,19 +0,0 @@
1
- jQuery(document).ready(function() {
2
- var lastSel = jQuery('#workflow_id option:selected');
3
- // try new rollback here.
4
- jQuery('select').change(function(e) {
5
-
6
- if (Workflow.workflows.hasOwnProperty(this.value))
7
- {
8
- var workflow = this.value;
9
- jQuery('#yes-' + workflow).attr('href', Workflow.workflows[this.value]);
10
-
11
- jQuery('#no-' + workflow).on('click', function() {
12
- lastSel.attr('selected', true);
13
- Workflow.modals.close_modal('TB_closeWindowButton');
14
- });
15
-
16
- tb_show('Default Settings', '#TB_inline?width=500&height=300&inlineId=modal-window-id-' + workflow);
17
- }
18
- });
19
- });
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
js/workflow/workflow.js CHANGED
@@ -2,6 +2,10 @@ Workflow = {};
2
 
3
  Workflow.modals = {};
4
 
 
 
 
 
5
  Workflow.modals.close_modal = function(id) {
6
  jQuery('#' + id).trigger('click');
7
  }
@@ -10,10 +14,73 @@ Workflow.modals.replace_href = function(element) {
10
  if (!jQuery(element).attr('url'))
11
  {
12
  jQuery(element).attr('url', jQuery(element).attr('href'));
 
13
  }
14
  return jQuery(element).attr('url');
15
  }
16
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
17
  Workflow.workflows = {
18
- 'professional-translation' : 'https://www.lingotek.com/'
19
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
2
 
3
  Workflow.modals = {};
4
 
5
+ Workflow.modals.get_ajax_url = function(action) {
6
+ return get_relative_url() + '/admin-ajax.php?action=' + action;
7
+ }
8
+
9
  Workflow.modals.close_modal = function(id) {
10
  jQuery('#' + id).trigger('click');
11
  }
14
  if (!jQuery(element).attr('url'))
15
  {
16
  jQuery(element).attr('url', jQuery(element).attr('href'));
17
+ jQuery(element).attr('href','#');
18
  }
19
  return jQuery(element).attr('url');
20
  }
21
 
22
+ Workflow.modals.get_url_parameter = function(name, url) {
23
+ var results = new RegExp('[\?&]' + name + '=([^&#]*)').exec(url);
24
+ return (results) ? results[1] : null;
25
+ }
26
+
27
+ Workflow.modals.ajax_request = function(type, ajax_url, body, callback) {
28
+ var request = jQuery.ajax({
29
+ url : ajax_url,
30
+ data : body,
31
+ type : type,
32
+ success : function(result) {
33
+ result = JSON.parse(result);
34
+ callback(result);
35
+ }
36
+ });
37
+ return request;
38
+ }
39
+
40
+ Workflow.modals.loading = function(id) {
41
+ Workflow.modals.show_modal(id, 'Lingotek Professional Translation Services', 550, 950);
42
+ jQuery('#TB_ajaxContent').find('*').not('.loading-element').hide();
43
+ jQuery('.loading-element').show();
44
+ }
45
+
46
+ Workflow.modals.show_modal = function(id, header_text, height, width) {
47
+ tb_show('<img src="' + workflow_vars.icon_url +'" style="padding-top:10px; display:inline-block"><span class="Upgrade-to-Lingotek header-professional">'+ header_text +'</span>', '#TB_inline?width='+ width +'&height='+ height +'&inlineId=modal-window-id-' + id);
48
+ Workflow.modals.add_header_modal(id);
49
+ }
50
+
51
+ Workflow.modals.add_header_modal = function(id) {
52
+ jQuery('#TB_title').css('height','55px');
53
+ jQuery('#TB_title').css('background-color','#3c3c3c');
54
+ jQuery('.tb-close-icon').css('color','white');
55
+ }
56
+
57
+ Workflow.modals.stop_loading = function(id, exceptions = '') {
58
+ jQuery('.loading-element').hide();
59
+ jQuery('#TB_ajaxContent').find('*').not('.loading-element' + ',' + exceptions).show();
60
+ }
61
+
62
+ Workflow.reset = function() {
63
+ jQuery('#TB_ajaxContent').find('*').remove();
64
+ }
65
+
66
+ Workflow.modals.get_relative_url = function() {
67
+ return get_relative_url();
68
+ }
69
+
70
  Workflow.workflows = {
71
+ 'ab6c522a-7645-4317-9284-3fbddf516151' : 'https://www.lingotek.com/'
72
+ }
73
+
74
+ Workflow.modals.show_payment_portal_loading_modal = function() {
75
+ tb_show('<img src="' + modal_vars.icon_url +'" style="padding-top:10px; display:inline-block"><span style="position:absolute; padding-top: 15px;"class="Upgrade-to-Lingotek">Lingotek Professional Translation Services</span>', '#TB_inline?width=800&height=400&inlineId=modal-window-id-' + professional_vars.workflow_id);
76
+ jQuery('#TB_title').css('height','55px');
77
+ jQuery('#TB_title').css('background-color','#3c3c3c');
78
+ jQuery('.tb-close-icon').css('color','white');
79
+ }
80
+
81
+ function get_relative_url() {
82
+ var url = window.location.href;
83
+ var end = url.indexOf('wp-admin') + 'wp-admin'.length;
84
+ return url.substring(0,end);
85
+ }
86
+
lingotek.php CHANGED
@@ -2,7 +2,7 @@
2
  /**
3
  Plugin name: Lingotek Translation
4
  Plugin URI: http://lingotek.com/wordpress#utm_source=wpadmin&utm_medium=plugin&utm_campaign=wplingotektranslationplugin
5
- Version: 1.2.9
6
  Author: Lingotek and Frédéric Demarle
7
  Author uri: http://lingotek.com
8
  Description: Lingotek offers convenient cloud-based localization and translation.
@@ -16,7 +16,7 @@ if ( ! function_exists( 'add_action' ) ) {
16
  exit();
17
  }
18
 
19
- define( 'LINGOTEK_VERSION', '1.2.9' ); // plugin version (should match above meta).
20
  define( 'LINGOTEK_MIN_PLL_VERSION', '1.8' );
21
  define( 'LINGOTEK_BASENAME', plugin_basename( __FILE__ ) ); // plugin name as known by WP.
22
  define( 'LINGOTEK_PLUGIN_SLUG', 'lingotek-translation' );// plugin slug (should match above meta: Text Domain).
@@ -25,7 +25,7 @@ define( 'LINGOTEK_INC', LINGOTEK_DIR . '/include' );
25
  define( 'LINGOTEK_ADMIN_INC', LINGOTEK_DIR . '/admin' );
26
  define( 'LINGOTEK_WORKFLOWS', LINGOTEK_ADMIN_INC . '/workflows' );
27
  define( 'LINGOTEK_URL', plugins_url( '', __FILE__ ) );
28
- define( 'BRIDGE_URL', 'https://27b9229a.ngrok.io' );
29
 
30
  class Lingotek {
31
  /**
@@ -46,6 +46,7 @@ class Lingotek {
46
  * Array to map Lingotek locales to WP locales.
47
  * map as 'WP locale' => 'Lingotek locale'.
48
  *
 
49
  * @var array
50
  */
51
  public static $lingotek_locales = array(
@@ -159,6 +160,282 @@ class Lingotek {
159
  'zh_TW' => 'zh-TW',
160
  );
161
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
162
  /**
163
  *
164
  * Unique identifier for your plugin.
@@ -238,31 +515,21 @@ class Lingotek {
238
 
239
  public function lingotek_plugin_migration() {
240
  $version = get_option('lingotek_plugin_version');
241
- if (!$version || $version < LINGOTEK_VERSION) {
242
  $this->do_plugin_updates();
243
  }
244
  update_option('lingotek_plugin_version', LINGOTEK_VERSION);
245
  }
246
 
247
  public function do_plugin_updates() {
248
- $content_type = get_option('lingotek_content_type');
249
- foreach ($content_type as &$content) {
250
- if (isset($content['profile']) && 'automatic' === $content['profile']) {
251
- $content['profile'] = 'manual';
252
- }
253
- }
254
- update_option('lingotek_content_type', $content_type);
255
 
256
-
257
- $profiles = get_option('lingotek_profiles');
258
- foreach ($profiles as $profile_name => &$configurations) {
259
- if ('automatic' !== $profile_name) {
260
- if (isset($configurations['upload']) && 'automatic' === $configurations['upload']) {
261
- $configurations['upload'] = 'manual';
262
- }
263
- }
264
  }
265
- update_option('lingotek_profiles', $profiles);
266
  }
267
 
268
  /**
2
  /**
3
  Plugin name: Lingotek Translation
4
  Plugin URI: http://lingotek.com/wordpress#utm_source=wpadmin&utm_medium=plugin&utm_campaign=wplingotektranslationplugin
5
+ Version: 1.3.0
6
  Author: Lingotek and Frédéric Demarle
7
  Author uri: http://lingotek.com
8
  Description: Lingotek offers convenient cloud-based localization and translation.
16
  exit();
17
  }
18
 
19
+ define( 'LINGOTEK_VERSION', '1.3.0' ); // plugin version (should match above meta).
20
  define( 'LINGOTEK_MIN_PLL_VERSION', '1.8' );
21
  define( 'LINGOTEK_BASENAME', plugin_basename( __FILE__ ) ); // plugin name as known by WP.
22
  define( 'LINGOTEK_PLUGIN_SLUG', 'lingotek-translation' );// plugin slug (should match above meta: Text Domain).
25
  define( 'LINGOTEK_ADMIN_INC', LINGOTEK_DIR . '/admin' );
26
  define( 'LINGOTEK_WORKFLOWS', LINGOTEK_ADMIN_INC . '/workflows' );
27
  define( 'LINGOTEK_URL', plugins_url( '', __FILE__ ) );
28
+ define( 'BRIDGE_URL', 'https://mw.lingotek.com' );
29
 
30
  class Lingotek {
31
  /**
46
  * Array to map Lingotek locales to WP locales.
47
  * map as 'WP locale' => 'Lingotek locale'.
48
  *
49
+ * TODO: update this list!!!!
50
  * @var array
51
  */
52
  public static $lingotek_locales = array(
160
  'zh_TW' => 'zh-TW',
161
  );
162
 
163
+ /**
164
+ * These are the locale codes that TMS can handle and process. Because polylang allows users to create
165
+ * their own custom languages and locales we want to verify that we are able to handle a locale before we start
166
+ * tracking it and allow the user to request translations for it.
167
+ *
168
+ * @var array
169
+ */
170
+ public static $allowed_tms_locales = array(
171
+ 'ab-GE' => 'ab_GE',
172
+ 'af-ZA' => 'af_ZA',
173
+ 'ak-GH' => 'ak_GH',
174
+ 'am-ET' => 'am_ET',
175
+ 'apa-US' => 'apa_US',
176
+ 'ar-AE' => 'ar_AE',
177
+ 'ar-AF' => 'ar_AF',
178
+ 'ar-BH' => 'ar_BH',
179
+ 'ar-DZ' => 'ar_DZ',
180
+ 'ar-EG' => 'ar_EG',
181
+ 'ar-IQ' => 'ar_IQ',
182
+ 'ar-JO' => 'ar_JO',
183
+ 'ar-LY' => 'ar_LY',
184
+ 'ar-MA' => 'ar_MA',
185
+ 'ar-MR' => 'ar_MR',
186
+ 'ar-OM' => 'ar_OM',
187
+ 'ar-SA' => 'ar_SA',
188
+ 'ar-SD' => 'ar_SD',
189
+ 'ar-SY' => 'ar_SY',
190
+ 'ar-TD' => 'ar_TD',
191
+ 'ar-TN' => 'ar_TN',
192
+ 'ar-UZ' => 'ar_UZ',
193
+ 'ar-YE' => 'ar_YE',
194
+ 'as-IN' => 'as_IN',
195
+ 'ast-ES' => 'ast_ES',
196
+ 'ay-BO' => 'ay_BO',
197
+ 'az-AZ' => 'az_AZ',
198
+ 'ba-RU' => 'ba_RU',
199
+ 'be-BY' => 'be_BY',
200
+ 'bg-BG' => 'bg_BG',
201
+ 'bi-VU' => 'bi_VU',
202
+ 'bik-PH' => 'bik_PH',
203
+ 'bm-ML' => 'bm_ML',
204
+ 'bn-BD' => 'bn_BD',
205
+ 'bo-CN' => 'bo_CN',
206
+ 'br-FR' => 'br_FR',
207
+ 'bs-BA' => 'bs_BA',
208
+ 'ca-ES' => 'ca_ES',
209
+ 'ce-RU' => 'ce_RU',
210
+ 'ceb-PH' => 'ceb_PH',
211
+ 'ch-GU' => 'ch_GU',
212
+ 'chr-US' => 'chr_US',
213
+ 'chy-US' => 'chy_US',
214
+ 'co-FR' => 'co_FR',
215
+ 'cs-CZ' => 'cs_CZ',
216
+ 'cy-GB' => 'cy_GB',
217
+ 'da-DK' => 'da_DK',
218
+ 'de-DE' => 'de_DE',
219
+ 'dik-SD' => 'dik_SD',
220
+ 'dv-MV' => 'dv_MV',
221
+ 'dz-BT' => 'dz_BT',
222
+ 'ee-GH' => 'ee_GH',
223
+ 'efi-NG' => 'efi_NG',
224
+ 'el-GR' => 'el_GR',
225
+ 'en-AU' => 'en_AU',
226
+ 'en-CA' => 'en_CA',
227
+ 'en-GB' => 'en_GB',
228
+ 'en-US' => 'en_US',
229
+ 'en-ZA' => 'en_ZA',
230
+ 'eo-FR' => 'eo_FR',
231
+ 'es-AR' => 'es_AR',
232
+ 'es-BO' => 'es_BO',
233
+ 'es-CL' => 'es_CL',
234
+ 'es-CO' => 'es_CO',
235
+ 'es-CR' => 'es_CR',
236
+ 'es-CU' => 'es_CU',
237
+ 'es-DO' => 'es_DO',
238
+ 'es-EC' => 'es_EC',
239
+ 'es-ES' => 'es_ES',
240
+ 'es-GT' => 'es_GT',
241
+ 'es-HN' => 'es_HN',
242
+ 'es-MX' => 'es_MX',
243
+ 'es-NI' => 'es_NI',
244
+ 'es-PA' => 'es_PA',
245
+ 'es-PE' => 'es_PE',
246
+ 'es-PR' => 'es_PR',
247
+ 'es-PY' => 'es_PY',
248
+ 'es-SV' => 'es_SV',
249
+ 'es-UY' => 'es_UY',
250
+ 'es-VE' => 'es_VE',
251
+ 'et-EE' => 'et_EE',
252
+ 'eu-ES' => 'eu_ES',
253
+ 'fa-IR' => 'fa_IR',
254
+ 'fat-GH' => 'fat_GH',
255
+ 'fi-FI' => 'fi_FI',
256
+ 'fj-FJ' => 'fj_FJ',
257
+ 'fj-IN' => 'fj_IN',
258
+ 'fon-BJ' => 'fon_BJ',
259
+ 'fr-CA' => 'fr_CA',
260
+ 'fr-FR' => 'fr_FR',
261
+ 'gaa-GH' => 'gaa_GH',
262
+ 'gbz-IR' => 'gbz_IR',
263
+ 'gil-KI' => 'gil_KI',
264
+ 'gl-ES' => 'gl_ES',
265
+ 'gn-BO' => 'gn_BO',
266
+ 'gu-IN' => 'gu_IN',
267
+ 'ha-NG' => 'ha_NG',
268
+ 'haw-US' => 'haw_US',
269
+ 'he-IL' => 'he_IL',
270
+ 'hi-IN' => 'hi_IN',
271
+ 'hil-PH' => 'hil_PH',
272
+ 'hmn-LA' => 'hmn_LA',
273
+ 'hr-HR' => 'hr_HR',
274
+ 'ht-HT' => 'ht_HT',
275
+ 'hu-HU' => 'hu_HU',
276
+ 'hy-AM' => 'hy_AM',
277
+ 'id-ID' => 'id_ID',
278
+ 'ig-NG' => 'ig_NG',
279
+ 'ilo-PH' => 'ilo_PH',
280
+ 'is-IS' => 'is_IS',
281
+ 'it-IT' => 'it_IT',
282
+ 'ja-JP' => 'ja_JP',
283
+ 'jv-ID' => 'jv_ID',
284
+ 'ka-GE' => 'ka_GE',
285
+ 'kek-GT' => 'kek_GT',
286
+ 'kg-CD' => 'kg_CD',
287
+ 'kik-KE' => 'kik_KE',
288
+ 'kin-RW' => 'kin_RW',
289
+ 'kj-AO' => 'kj_AO',
290
+ 'kk-KZ' => 'kk_KZ',
291
+ 'km-KH' => 'km_KH',
292
+ 'kn-IN' => 'kn_IN',
293
+ 'ko-KR' => 'ko_KR',
294
+ 'kos-FM' => 'kos_FM',
295
+ 'ks-IN' => 'ks_IN',
296
+ 'ku-IQ' => 'ku_IQ',
297
+ 'kw-GB' => 'kw_GB',
298
+ 'ky-KG' => 'ky_KG',
299
+ 'la-VA' => 'la_VA',
300
+ 'lb-LU' => 'lb_LU',
301
+ 'lg-UG' => 'lg_UG',
302
+ 'ln-CD' => 'ln_CD',
303
+ 'lo-LA' => 'lo_LA',
304
+ 'lt-LT' => 'lt_LT',
305
+ 'lu-CD' => 'lu_CD',
306
+ 'lv-LV' => 'lv_LV',
307
+ 'mg-MG' => 'mg_MG',
308
+ 'mh-MH' => 'mh_MH',
309
+ 'mi-NZ' => 'mi_NZ',
310
+ 'mk-MK' => 'mk_MK',
311
+ 'ml-IN' => 'ml_IN',
312
+ 'mn-MN' => 'mn_MN',
313
+ 'mo-MD' => 'mo_MD',
314
+ 'mr-IN' => 'mr_IN',
315
+ 'ms-MY' => 'ms_MY',
316
+ 'mt-MT' => 'mt_MT',
317
+ 'my-MM' => 'my_MM',
318
+ 'na-NR' => 'na_NR',
319
+ 'nb-NO' => 'nb_NO',
320
+ 'nd-ZW' => 'nd_ZW',
321
+ 'ne-NP' => 'ne_NP',
322
+ 'ng-NA' => 'ng_NA',
323
+ 'niu-NU' => 'niu_NU',
324
+ 'nl-NL' => 'nl_NL',
325
+ 'nn-NO' => 'nn_NO',
326
+ 'no-NO' => 'no_NO',
327
+ 'nr-ZA' => 'nr_ZA',
328
+ 'nso-ZA' => 'nso_ZA',
329
+ 'nv-US' => 'nv_US',
330
+ 'ny-MW' => 'ny_MW',
331
+ 'om-ET' => 'om_ET',
332
+ 'or-IN' => 'or_IN',
333
+ 'pag-PH' => 'pag_PH',
334
+ 'pap-AN' => 'pap_AN',
335
+ 'pau-PW' => 'pau_PW',
336
+ 'pl-PL' => 'pl_PL',
337
+ 'ps-AF' => 'ps_AF',
338
+ 'pt-BR' => 'pt_BR',
339
+ 'pt-PT' => 'pt_PT',
340
+ 'qu-BO' => 'qu_BO',
341
+ 'rar-CK' => 'rar_CK',
342
+ 'rn-BI' => 'rn_BI',
343
+ 'ro-RO' => 'ro_RO',
344
+ 'ru-RU' => 'ru_RU',
345
+ 'sa-IN' => 'sa_IN',
346
+ 'qu-PE' => 'qu_PE',
347
+ 'sc-IT' => 'sc_IT',
348
+ 'scn-IT' => 'scn_IT',
349
+ 'sd-PK' => 'sd_PK',
350
+ 'sg-CF' => 'sg_CF',
351
+ 'si-LK' => 'si_LK',
352
+ 'sk-SK' => 'sk_SK',
353
+ 'sl-SI' => 'sl_SI',
354
+ 'sm-WS' => 'sm_WS',
355
+ 'sn-ZW' => 'sn_ZW',
356
+ 'so-SO' => 'so_SO',
357
+ 'sq-SQ' => 'sq_SQ',
358
+ 'sr-CS' => 'sr_CS',
359
+ 'ss-SZ' => 'ss_SZ',
360
+ 'st-LS' => 'st_LS',
361
+ 'su-ID' => 'su_ID',
362
+ 'sv-SE' => 'sv_SE',
363
+ 'sw-TZ' => 'sw_TZ',
364
+ 'ta-IN' => 'ta_IN',
365
+ 'te-IN' => 'te_IN',
366
+ 'tg-TJ' => 'tg_TJ',
367
+ 'th-TH' => 'th_TH',
368
+ 'ti-ER' => 'ti_ER',
369
+ 'tk-TM' => 'tk_TM',
370
+ 'tl-PH' => 'tl_PH',
371
+ 'tn-BW' => 'tn_BW',
372
+ 'to-TO' => 'to_TO',
373
+ 'tpi-PG' => 'tpi_PG',
374
+ 'tr-TR' => 'tr_TR',
375
+ 'ts-ZA' => 'ts_ZA',
376
+ 'tum-MW' => 'tum_MW',
377
+ 'tvl-TV' => 'tvl_TV',
378
+ 'tw-GH' => 'tw_GH',
379
+ 'ty-PF' => 'ty_PF',
380
+ 'ug-CN' => 'ug_CN',
381
+ 'uk-UA' => 'uk_UA',
382
+ 'um-AO' => 'um_AO',
383
+ 'ur-PK' => 'ur_PK',
384
+ 'uz-UZ' => 'uz_UZ',
385
+ 've-ZA' => 've_ZA',
386
+ 'vi-VN' => 'vi_VN',
387
+ 'war-PH' => 'war_PH',
388
+ 'wo-SN' => 'wo_SN',
389
+ 'xh-ZA' => 'xh_ZA',
390
+ 'yap-FM' => 'yap_FM',
391
+ 'yi-IL' => 'yi_IL',
392
+ 'yo-NG' => 'yo_NG',
393
+ 'zh-CN' => 'zh_CN',
394
+ 'zh-HK' => 'zh_HK',
395
+ 'zh-SG' => 'zh_SG',
396
+ 'zh-TW' => 'zh_TW',
397
+ 'zu-ZA' => 'zu_ZA',
398
+ 'es-US' => 'es_US',
399
+ 'fr-US' => 'fr_US',
400
+ 'gd-GB' => 'gd_GB',
401
+ 'ga-IE' => 'ga_IE',
402
+ 'pa-IN' => 'pa_IN',
403
+ 'pa-PK' => 'pa_PK',
404
+ 'nl-BE' => 'nl_BE',
405
+ 'de-CH' => 'de_CH',
406
+ 'it-CH' => 'it_CH',
407
+ 'fr-CH' => 'fr_CH',
408
+ 'de-AT' => 'de_AT',
409
+ 'chk-FM' => 'chk_FM',
410
+ 'pam-PH' => 'pam_PH',
411
+ 'pon-FM' => 'pon_FM',
412
+ 'prs-AF' => 'prs_AF',
413
+ 'aiq-AF' => 'aiq_AF',
414
+ 'haz-AF' => 'haz_AF',
415
+ 'cpe-US' => 'cpe_US',
416
+ 'cpf-MU' => 'cpf_MU',
417
+ 'cpp-BR' => 'cpp_BR',
418
+ 'ar' => 'ar',
419
+ 'aa-DJ' => 'aa_DJ',
420
+ 'en-IE' => 'en_IE',
421
+ 'es-419' => 'es_419',
422
+ 'en-IN' => 'en_IN',
423
+ 'fr-BE' => 'fr_BE',
424
+ 'vls-BE' => 'vls_BE',
425
+ );
426
+
427
+ /**
428
+ * Verifies that a lingotek-locale (ie. es-ES) is an allowed
429
+ * TMS locale.
430
+ *
431
+ * @param string $lingotek_locale
432
+ * @return boolean
433
+ */
434
+ public static function is_allowed_tms_locale($lingotek_locale)
435
+ {
436
+ return isset(self::$allowed_tms_locales[$lingotek_locale]);
437
+ }
438
+
439
  /**
440
  *
441
  * Unique identifier for your plugin.
515
 
516
  public function lingotek_plugin_migration() {
517
  $version = get_option('lingotek_plugin_version');
518
+ if ($version != LINGOTEK_VERSION) {
519
  $this->do_plugin_updates();
520
  }
521
  update_option('lingotek_plugin_version', LINGOTEK_VERSION);
522
  }
523
 
524
  public function do_plugin_updates() {
525
+ $cr = get_option('lingotek_community_resources');
526
+ if (is_array($cr) && isset($cr['workflows'])) {
527
+ // unset($cr['workflows']['ab6c522a-7645-4317-9284-3fbddf516151']);
 
 
 
 
528
 
529
+ // put Lingotek Professional Translation at the top of the select box.
530
+ $cr['workflows'] = array_merge(array('ab6c522a-7645-4317-9284-3fbddf516151' => 'Lingotek Professional Translation'), $cr['workflows']);
531
+ update_option('lingotek_community_resources', $cr);
 
 
 
 
 
532
  }
 
533
  }
534
 
535
  /**
readme.txt CHANGED
@@ -3,8 +3,8 @@ Contributors: chouby, smithworx, erichie, robertdhanna
3
  Donate link: http://lingotek.com/
4
  Tags: automation, bilingual, international, language, Lingotek, localization, multilanguage, multilingual, translate, translation
5
  Requires at least: 3.8
6
- Tested up to: 4.7
7
- Stable tag: 1.2.9
8
  License: GPLv2 or later
9
  License URI: http://www.gnu.org/licenses/gpl-2.0.html
10
 
@@ -122,6 +122,11 @@ For more, visit the [Lingotek documentation site](https://lingotek.atlassian.net
122
 
123
  == Changelog ==
124
 
 
 
 
 
 
125
  = 1.2.9 (2017-6-15) =
126
 
127
  * Fixed a bug that displayed an error upon installing the plugin.
3
  Donate link: http://lingotek.com/
4
  Tags: automation, bilingual, international, language, Lingotek, localization, multilanguage, multilingual, translate, translation
5
  Requires at least: 3.8
6
+ Tested up to: 4.8
7
+ Stable tag: 1.3.0
8
  License: GPLv2 or later
9
  License URI: http://www.gnu.org/licenses/gpl-2.0.html
10
 
122
 
123
  == Changelog ==
124
 
125
+ = 1.3.0 (2017-7-10) =
126
+
127
+ * Added the Lingotek Professional Translation workflow.
128
+ * Fixed a bug that was showing the incorrect profile type.
129
+
130
  = 1.2.9 (2017-6-15) =
131
 
132
  * Fixed a bug that displayed an error upon installing the plugin.