@lancom/shared 0.0.383 → 0.0.384

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (54) hide show
  1. package/assets/js/api/index.js +3 -0
  2. package/components/checkout/cart/cart.mixin.js +5 -1
  3. package/components/checkout/cart/cart.vue +8 -20
  4. package/components/checkout/cart/cart_price_info/cart-price-info.vue +8 -53
  5. package/components/checkout/cart/cart_pricing/cart-pricing.scss +11 -3
  6. package/components/checkout/cart/cart_pricing/cart-pricing.vue +6 -2
  7. package/components/checkout/cart/cart_shipments_pricing/cart-shipments-pricing.scss +3 -0
  8. package/components/checkout/cart/cart_shipments_pricing/cart-shipments-pricing.vue +12 -2
  9. package/components/checkout/cart/cart_shipping/cart-shipping.scss +43 -0
  10. package/components/checkout/cart/cart_shipping/cart-shipping.vue +126 -0
  11. package/components/checkout/order/address-form/address-form.vue +5 -0
  12. package/components/checkout/order/order-billing-information/order-billing-information.vue +1 -0
  13. package/components/checkout/order/order-payment-information/order-payment-information.vue +9 -0
  14. package/components/common/payment/payment_card/applepay/applepay.scss +8 -0
  15. package/components/common/payment/payment_card/applepay/applepay.vue +16 -0
  16. package/components/common/payment/payment_card/payment-card.vue +7 -0
  17. package/components/common/postcode_select/postcode-select.scss +6 -0
  18. package/components/common/postcode_select/postcode-select.vue +16 -6
  19. package/components/common/pricing_discounts_table/pricing-discounts-table.vue +12 -2
  20. package/components/customer/customer_coupons/customer-coupons.scss +33 -0
  21. package/components/customer/customer_coupons/customer-coupons.vue +103 -0
  22. package/components/customer/customer_coupons/customer_coupon_apply/customer-coupon-apply.scss +1 -0
  23. package/components/customer/customer_coupons/customer_coupon_apply/customer-coupon-apply.vue +51 -0
  24. package/components/customer/customer_coupons/customer_coupon_prints/customer-coupon-prints.scss +1 -0
  25. package/components/customer/customer_coupons/customer_coupon_prints/customer-coupon-prints.vue +33 -0
  26. package/components/customer/customer_coupons/customer_coupon_prints/customer_coupon_print/customer-coupon-print.scss +19 -0
  27. package/components/customer/customer_coupons/customer_coupon_prints/customer_coupon_print/customer-coupon-print.vue +82 -0
  28. package/components/customer/customer_coupons/customer_coupon_products/customer-coupon-products.scss +1 -0
  29. package/components/customer/customer_coupons/customer_coupon_products/customer-coupon-products.vue +33 -0
  30. package/components/customer/customer_coupons/customer_coupon_products/customer_coupon_product/customer-coupon-product.scss +17 -0
  31. package/components/customer/customer_coupons/customer_coupon_products/customer_coupon_product/customer-coupon-product.vue +52 -0
  32. package/components/customer/customer_navigation_menu/customer-navigation-menu.vue +72 -0
  33. package/components/customer/customer_orders/customer-orders.scss +26 -12
  34. package/components/customer/customer_orders/customer-orders.vue +64 -33
  35. package/components/customer/customer_orders/customer_order_reorder/customer-order-reorder.scss +1 -0
  36. package/components/customer/customer_orders/customer_order_reorder/customer-order-reorder.vue +55 -0
  37. package/components/customer/customer_orders/customer_order_trackings/customer-order-trackings.scss +8 -0
  38. package/components/customer/customer_orders/customer_order_trackings/customer-order-trackings.vue +38 -0
  39. package/components/quotes/quote_view/quote-view.vue +1 -0
  40. package/components/quotes/quote_view/quote_option_view/quote-option-view.vue +4 -0
  41. package/components/quotes/quote_view/quote_product_color_simple_products/quote-product-color-simple-products.vue +9 -2
  42. package/components/quotes/quote_view/quote_product_color_simple_products/quote_product_color_simple_product/quote-product-color-simple-product.scss +54 -1
  43. package/components/quotes/quote_view/quote_product_color_simple_products/quote_product_color_simple_product/quote-product-color-simple-product.vue +83 -5
  44. package/components/quotes/quote_view/quote_view_product/quote-view-product.scss +7 -0
  45. package/components/quotes/quote_view/quote_view_product/quote-view-product.vue +33 -11
  46. package/feeds/google-shopping.js +10 -4
  47. package/package.json +1 -1
  48. package/pages/checkout/order.vue +13 -4
  49. package/pages/customer/coupons.vue +39 -0
  50. package/pages/customer/orders.vue +39 -0
  51. package/pages/customer/settings.vue +4 -2
  52. package/routes/index.js +6 -1
  53. package/store/cart.js +1 -1
  54. package/pages/customer/orders/index.vue +0 -29
@@ -0,0 +1,33 @@
1
+ @import "@/assets/scss/variables";
2
+
3
+ .CustomerCoupons__wrapper {
4
+ .VueTables {
5
+ &__table {
6
+ width: 100%;
7
+ border-collapse: collapse;
8
+ th, td {
9
+ padding: 10px;
10
+ text-align: left;
11
+ border-bottom: 1px solid $grey_2;
12
+ font-size: 14px;
13
+ &:nth-child(-n+3) {
14
+ width: 220px;
15
+ }
16
+ }
17
+ th {
18
+ background-color: $grey_3;
19
+ font-weight: bold;
20
+ }
21
+ a {
22
+ color: $black;
23
+ text-decoration: none;
24
+ transition: color 0.2s ease;
25
+
26
+ &:hover {
27
+ color: darken($black, 10%);
28
+ text-decoration: underline;
29
+ }
30
+ }
31
+ }
32
+ }
33
+ }
@@ -0,0 +1,103 @@
1
+ <template>
2
+ <div class="CustomerCoupons__wrapper">
3
+ <client-only>
4
+ <v-server-table
5
+ :key="uniqueKey"
6
+ ref="table"
7
+ :columns="columns"
8
+ :options="options">
9
+ <template #value="{ row }">
10
+ <div v-if="row.percentValue || row.value">
11
+ {{ row.percentValue ? `${row.percentValue}%` : price(row.value) }}
12
+ </div>
13
+ </template>
14
+ <template #minOrderValue="{ row }">
15
+ {{ row.minOrderValue ? price(row.minOrderValue) : '' }}
16
+ </template>
17
+ <template #items="{ row }">
18
+ <div>
19
+ <customer-coupon-products
20
+ v-if="row.products && row.products.length > 0"
21
+ :coupon="row" />
22
+ <customer-coupon-prints
23
+ v-if="row.prints && row.prints.length > 0"
24
+ :coupon="row" />
25
+ </div>
26
+ </template>
27
+ <template #apply="{ row }">
28
+ <div class="CustomerCoupon__apply">
29
+ <customer-coupon-apply :coupon="row" />
30
+ </div>
31
+ </template>
32
+ </v-server-table>
33
+ </client-only>
34
+ </div>
35
+ </template>
36
+
37
+ <script>
38
+ import { mapGetters } from 'vuex';
39
+ import Vue from 'vue';
40
+ import { ServerTable } from 'vue-tables-2';
41
+ import CustomerCouponApply from './customer_coupon_apply/customer-coupon-apply';
42
+ import CustomerCouponPrints from './customer_coupon_prints/customer-coupon-prints';
43
+ import CustomerCouponProducts from './customer_coupon_products/customer-coupon-products';
44
+ import { _get } from '@lancom/shared/assets/js/api/helpers';
45
+ import { price } from '@lancom/shared/assets/js/utils/filters';
46
+
47
+ Vue.use(ServerTable);
48
+
49
+ export default {
50
+ name: 'CustomerCoupons',
51
+ components: {
52
+ CustomerCouponApply,
53
+ CustomerCouponPrints,
54
+ CustomerCouponProducts
55
+ },
56
+ props: {
57
+ customer: {
58
+ type: Object,
59
+ required: true
60
+ }
61
+ },
62
+ data() {
63
+ return {
64
+ uniqueKey: Date.now(),
65
+ orders: [],
66
+ columns: ['name', 'code', 'value', 'minOrderValue', 'items', 'apply']
67
+ }
68
+ },
69
+ computed: {
70
+ ...mapGetters(['shop']),
71
+ url() {
72
+ return `shop/${this.shop._id}/customer/${this.customer._id}/coupons`;
73
+ },
74
+ options() {
75
+ return {
76
+ query: null,
77
+ perPage: 15,
78
+ perPageValues: [15],
79
+ initialPage: 1,
80
+ filterable: false,
81
+ headings: { select: '' },
82
+ requestFunction: params => this.request(params),
83
+ columnsClasses: {
84
+ controls: 'controls-column'
85
+ }
86
+ };
87
+ }
88
+ },
89
+ methods: {
90
+ price,
91
+ async request(params) {
92
+ const query = { ...params };
93
+ const result = await _get(this.url, query);
94
+ return result;
95
+ },
96
+ }
97
+ };
98
+ </script>
99
+
100
+ <style lang="scss">
101
+ @import 'customer-coupons';
102
+ </style>
103
+
@@ -0,0 +1 @@
1
+ @import "@/assets/scss/variables";
@@ -0,0 +1,51 @@
1
+ <template>
2
+ <div class="CustomerCouponApply__wrapper">
3
+ <btn
4
+ btn-class="green"
5
+ :btn-disabled="processing"
6
+ :btn-processing="processing"
7
+ btn-label="Coupon Apply"
8
+ @onclick="applyCoupon()">
9
+ </btn>
10
+ </div>
11
+ </template>
12
+
13
+ <script>
14
+ import { mapMutations } from 'vuex';
15
+
16
+ export default {
17
+ name: 'CustomerCouponApply',
18
+ data() {
19
+ return {
20
+ processing: false
21
+ }
22
+ },
23
+ props: {
24
+ coupon: {
25
+ type: Object,
26
+ required: true
27
+ }
28
+ },
29
+ methods: {
30
+ ...mapMutations('cart', [
31
+ 'setCoupon'
32
+ ]),
33
+ async applyCoupon() {
34
+ try {
35
+ this.processing = true;
36
+ this.setCoupon(this.coupon);
37
+ this.$router.push('/checkout/cart');
38
+ } catch (e) {
39
+ console.log(e);
40
+ } finally {
41
+ this.processing = false;
42
+ }
43
+ }
44
+ }
45
+ };
46
+ </script>
47
+
48
+ <style lang="scss">
49
+ @import 'customer-coupon-apply';
50
+ </style>
51
+
@@ -0,0 +1,33 @@
1
+ <template>
2
+ <div class="CustomerCouponPrints__wrapper">
3
+ <div class="lc_h5 mb-5 mt-5">Prints</div>
4
+ <CustomerCouponPrint
5
+ v-for="(print, index) in coupon.prints"
6
+ :key="index"
7
+ :coupon="coupon"
8
+ :print="print"
9
+ />
10
+ </div>
11
+ </template>
12
+
13
+ <script>
14
+ import CustomerCouponPrint from './customer_coupon_print/customer-coupon-print';
15
+
16
+ export default {
17
+ name: 'CustomerCouponPrints',
18
+ components: {
19
+ CustomerCouponPrint
20
+ },
21
+ props: {
22
+ coupon: {
23
+ type: Object,
24
+ required: true
25
+ }
26
+ }
27
+ };
28
+ </script>
29
+
30
+ <style lang="scss">
31
+ @import 'customer-coupon-prints';
32
+ </style>
33
+
@@ -0,0 +1,19 @@
1
+ @import "@/assets/scss/variables";
2
+
3
+ .CustomerCouponPrint {
4
+ &__wrapper {
5
+ .lc_table {
6
+ tr {
7
+ height: 38px;
8
+ }
9
+ td, th {
10
+ padding: 2px 0px !important;
11
+ }
12
+ }
13
+ }
14
+ &__print-types,
15
+ &__print-areas,
16
+ &__print-sizes {
17
+ display: flex;
18
+ }
19
+ }
@@ -0,0 +1,82 @@
1
+ <template>
2
+ <div class="CustomerCouponPrint__wrapper">
3
+ <div class="CustomerCouponPrint__print-types mb-4">
4
+ <div
5
+ v-for="(printType, index) in printTypes"
6
+ :key="index">
7
+ {{ index > 0 ? ', ' : '' }}<b>{{ printType.name }}</b>
8
+ </div>
9
+ </div>
10
+ <div v-for="(printArea, index) in printAreas" :key="index">
11
+ <div
12
+ v-if="printArea.freeSetupOver > 0"
13
+ class="mb-4">
14
+ Free Setup Over <b>{{ printArea.freeSetupOver | price(currency) }}</b>
15
+ </div>
16
+ <div
17
+ v-if="printArea.setupCost > 0"
18
+ class="mb-4">
19
+ Setup Cost <b>{{ printArea.setupCost | price(currency) }}</b>
20
+ </div>
21
+ <div
22
+ v-if="printArea.printSizes"
23
+ class="CustomerCouponPrint__print-sizes mb-4">
24
+ <div class="mr-5">Size: </div>
25
+ <div
26
+ v-for="(printSize, index) in printArea.printSizes"
27
+ :key="index">
28
+ {{ index > 0 ? ', ' : '' }}<b>{{ printSize.name }}</b>
29
+ </div>
30
+ </div>
31
+ <pricing-discounts-table
32
+ class="mt-4"
33
+ :prices="printArea.printCost"
34
+ :bordered="true"
35
+ :with-gst="false" />
36
+ </div>
37
+
38
+ </div>
39
+ </template>
40
+
41
+ <script>
42
+ import { mapGetters } from 'vuex';
43
+ import { price } from '@lancom/shared/assets/js/utils/filters';
44
+ import PricingDiscountsTable from '@lancom/shared/components/common/pricing_discounts_table/pricing-discounts-table';
45
+
46
+ export default {
47
+ name: 'CustomerCouponPrint',
48
+ filters: {
49
+ price
50
+ },
51
+ components: {
52
+ PricingDiscountsTable
53
+ },
54
+ props: {
55
+ coupon: {
56
+ type: Object,
57
+ required: true
58
+ },
59
+ print: {
60
+ type: Object,
61
+ required: true
62
+ }
63
+ },
64
+ computed: {
65
+ ...mapGetters(['currency']),
66
+ printTypes() {
67
+ return this.print.printTypes || [];
68
+ },
69
+ printAreas() {
70
+ return this.print.printAreas || [];
71
+ }
72
+ },
73
+ mounted() {
74
+ console.log('print: ', this.print);
75
+ }
76
+ };
77
+ </script>
78
+
79
+ <style lang="scss">
80
+ @import 'customer-coupon-print';
81
+ </style>
82
+
@@ -0,0 +1,33 @@
1
+ <template>
2
+ <div class="CustomerCouponProducts__wrapper">
3
+ <div class="lc_h5 mb-5 mt-5">Products</div>
4
+ <CustomerCouponProduct
5
+ v-for="(product, index) in coupon.products"
6
+ :key="index"
7
+ :coupon="coupon"
8
+ :product="product"
9
+ />
10
+ </div>
11
+ </template>
12
+
13
+ <script>
14
+ import CustomerCouponProduct from './customer_coupon_product/customer-coupon-product';
15
+
16
+ export default {
17
+ name: 'CustomerCouponProducts',
18
+ components: {
19
+ CustomerCouponProduct
20
+ },
21
+ props: {
22
+ coupon: {
23
+ type: Object,
24
+ required: true
25
+ }
26
+ }
27
+ };
28
+ </script>
29
+
30
+ <style lang="scss">
31
+ @import 'customer-coupon-products';
32
+ </style>
33
+
@@ -0,0 +1,17 @@
1
+ @import "@/assets/scss/variables";
2
+
3
+ .CustomerCouponProduct {
4
+ &__wrapper {
5
+ .lc_table {
6
+ tr {
7
+ height: 38px;
8
+ }
9
+ td, th {
10
+ padding: 2px 0px !important;
11
+ }
12
+ }
13
+ }
14
+ &__products {
15
+ display: flex;
16
+ }
17
+ }
@@ -0,0 +1,52 @@
1
+ <template>
2
+ <div class="CustomerCouponProduct__wrapper">
3
+ <div>
4
+ <ul class="CustomerCouponProduct__products">
5
+ <li v-for="(product, index) in products" :key="index">
6
+ {{ index > 0 ? ', ' : '' }}<b>{{ product.name }}</b>
7
+ </li>
8
+ </ul>
9
+ </div>
10
+ <div
11
+ v-if="product.onlyPrinted"
12
+ class="lc_regular14 mt-4">
13
+ Only Printed: <b>Yes</b>
14
+ </div>
15
+ <pricing-discounts-table
16
+ class="mt-4"
17
+ :prices="product.pricing"
18
+ :bordered="true"
19
+ :with-gst="false" />
20
+ </div>
21
+ </template>
22
+
23
+ <script>
24
+ import PricingDiscountsTable from '@lancom/shared/components/common/pricing_discounts_table/pricing-discounts-table';
25
+
26
+ export default {
27
+ name: 'CustomerCouponProduct',
28
+ components: {
29
+ PricingDiscountsTable
30
+ },
31
+ props: {
32
+ coupon: {
33
+ type: Object,
34
+ required: true
35
+ },
36
+ product: {
37
+ type: Object,
38
+ required: true
39
+ }
40
+ },
41
+ computed: {
42
+ products() {
43
+ return this.product.products || [];
44
+ }
45
+ }
46
+ };
47
+ </script>
48
+
49
+ <style lang="scss">
50
+ @import 'customer-coupon-product';
51
+ </style>
52
+
@@ -0,0 +1,72 @@
1
+ <template>
2
+ <div class="CustomerMenu__wrapper">
3
+ <div
4
+ v-for="menuItem of menuItems"
5
+ :key="menuItem.key"
6
+ :class="{ 'active': menuItem.key === activeMenuItem }"
7
+ class="CustomerMenu__menu-item">
8
+ <a :href="menuItem.url">
9
+ {{ menuItem.label }}
10
+ </a>
11
+ </div>
12
+ </div>
13
+ </template>
14
+
15
+ <script>
16
+ export default {
17
+ name: 'CustomerMenu',
18
+ data() {
19
+ return {
20
+ menuItems: [{
21
+ label: 'Settings',
22
+ key: 'settings',
23
+ url: '/customer/settings'
24
+ }, {
25
+ label: 'Orders',
26
+ key: 'orders',
27
+ url: '/customer/orders'
28
+ }, {
29
+ label: 'Coupons',
30
+ key: 'coupons',
31
+ url: '/customer/coupons'
32
+ }]
33
+ };
34
+ },
35
+ props: {
36
+ activeMenuItem: {
37
+ type: String,
38
+ required: true
39
+ }
40
+ }
41
+ };
42
+ </script>
43
+
44
+ <style lang="scss" scoped>
45
+ @import "@/assets/scss/variables";
46
+
47
+ .CustomerMenu {
48
+ &__wrapper {
49
+ display: flex;
50
+ margin-bottom: 10px;
51
+ }
52
+ &__menu-item {
53
+ a {
54
+ display: inline-block;
55
+ padding: 10px 20px;
56
+ cursor: pointer;
57
+ color: $black;
58
+ text-decoration: none;
59
+ border: 1px solid $green;
60
+ margin-right: 5px;
61
+ &:hover {
62
+ background-color: #f0f0f0;
63
+ }
64
+ }
65
+ &.active a {
66
+ font-weight: bold;
67
+ color: $black;
68
+ background-color: $green;
69
+ }
70
+ }
71
+ }
72
+ </style>
@@ -1,19 +1,33 @@
1
1
  @import "@/assets/scss/variables";
2
2
 
3
- .CustomerOrders {
4
- &__wrapper {
5
- position: relative;
6
- }
7
- &__table {
8
- th {
9
- font-weight: bold;
10
- }
11
- td {
12
- padding: 15px;
13
- a {
14
- color: $purple;
3
+ .CustomerOrders__wrapper {
4
+ .VueTables {
5
+ &__table {
6
+ width: 100%;
7
+ border-collapse: collapse;
8
+ th, td {
9
+ padding: 10px;
10
+ text-align: left;
11
+ border-bottom: 1px solid $grey_2;
12
+ font-size: 14px;
13
+ &:nth-child(-n+3) {
14
+ width: 220px;
15
+ }
16
+ }
17
+ th {
18
+ background-color: $grey_3;
15
19
  font-weight: bold;
16
20
  }
21
+ a {
22
+ color: $black;
23
+ text-decoration: none;
24
+ transition: color 0.2s ease;
25
+
26
+ &:hover {
27
+ color: darken($black, 10%);
28
+ text-decoration: underline;
29
+ }
30
+ }
17
31
  }
18
32
  }
19
33
  }
@@ -1,40 +1,53 @@
1
1
  <template>
2
2
  <div class="CustomerOrders__wrapper">
3
- <table class="lc_table bordered CustomerOrders__table">
4
- <thead class="centered">
5
- <tr>
6
- <th>Created At</th>
7
- <th>Code</th>
8
- <th>Status</th>
9
- </tr>
10
- </thead>
11
- <tbody>
12
- <tr
13
- v-for="order of orders"
14
- :key="order._id">
15
- <td>{{ order.createdAt | date }}</td>
16
- <td>
17
- <a
18
- :href="`/order/${order.token}`"
19
- target="_blank">
20
- {{ order.code }}
21
- </a>
22
- </td>
23
- <td>{{ order.status }}</td>
24
- </tr>
25
- </tbody>
26
- </table>
3
+ <client-only>
4
+ <v-server-table
5
+ :key="uniqueKey"
6
+ ref="table"
7
+ :columns="columns"
8
+ :options="options">
9
+ <template #createdAt="{ row }">
10
+ {{ row.createdAt | date }}
11
+ </template>
12
+ <template #code="{ row }">
13
+ <a
14
+ :href="`/order/${row.token}`"
15
+ target="_blank">
16
+ {{ row.code }}
17
+ </a>
18
+ </template>
19
+ <template #tracking="{ row }">
20
+ <div class="CustomerOrders__trackings">
21
+ <customer-order-trackings :order="row" />
22
+ </div>
23
+ </template>
24
+ <template #reorder="{ row }">
25
+ <div class="CustomerOrders__reorder">
26
+ <customer-order-reorder :order="row" />
27
+ </div>
28
+ </template>
29
+ </v-server-table>
30
+ </client-only>
27
31
  </div>
28
32
  </template>
29
33
 
30
34
  <script>
31
35
  import { mapGetters } from 'vuex';
32
- import api from '@lancom/shared/assets/js/api';
36
+ import Vue from 'vue';
37
+ import { ServerTable } from 'vue-tables-2';
33
38
  import { date } from '@lancom/shared/assets/js/utils/filters';
39
+ import CustomerOrderTrackings from './customer_order_trackings/customer-order-trackings';
40
+ import CustomerOrderReorder from './customer_order_reorder/customer-order-reorder';
41
+ import { _get } from './../../../assets/js/api/helpers';
34
42
 
43
+ Vue.use(ServerTable);
35
44
 
36
45
  export default {
37
46
  name: 'CustomerOrders',
47
+ components: {
48
+ CustomerOrderTrackings,
49
+ CustomerOrderReorder
50
+ },
38
51
  filters: {
39
52
  date
40
53
  },
@@ -46,19 +59,37 @@ export default {
46
59
  },
47
60
  data() {
48
61
  return {
49
- orders: []
62
+ uniqueKey: Date.now(),
63
+ orders: [],
64
+ columns: ['createdAt', 'status', 'code', 'totalGST', 'tracking', 'reorder']
50
65
  }
51
66
  },
52
67
  computed: {
53
- ...mapGetters(['contacts', 'shop']),
54
- },
55
- mounted() {
56
- this.locadCustomerOrders();
68
+ ...mapGetters(['shop']),
69
+ url() {
70
+ return `shop/${this.shop._id}/customer/${this.customer._id}/orders`;
71
+ },
72
+ options() {
73
+ return {
74
+ query: null,
75
+ perPage: 15,
76
+ perPageValues: [15],
77
+ initialPage: 1,
78
+ filterable: false,
79
+ headings: { select: '' },
80
+ requestFunction: params => this.request(params),
81
+ columnsClasses: {
82
+ controls: 'controls-column'
83
+ }
84
+ };
85
+ }
57
86
  },
58
87
  methods: {
59
- async locadCustomerOrders() {
60
- this.orders = await api.fetchCustomerOrders(this.customer, this.shop._id);
61
- }
88
+ async request(params) {
89
+ const query = { ...params };
90
+ const result = await _get(this.url, query);
91
+ return result;
92
+ },
62
93
  }
63
94
  };
64
95
  </script>
@@ -0,0 +1 @@
1
+ @import "@/assets/scss/variables";