JFIF $ d d 7 * Z qn )ZP 0 !1 A "#a$2Qr D8 a Ri [f \m I ykI w0 c u F c Rı?lO7 к _f˓ [C $殷WF< _W ԣ s Kc ëI zyQy /_LK ℂ ;C",p F A : /] =H ~ , l s / 9 ć: [=/#f ; ) x { ٛE Q )~ = 𘙲r*2~ a _V = ' ku m F D } KYYC )( { * g& f `툪 r y ` = ^ c J. I ]( * `wq 1dđ #̩ ͑ 0 ; H ] u 搂 @:~ ו K L N s h } O I R* 8 :2 ! lD JV o ( 3 = M ( z Ȱ+i *N A r6K n S l ) ! J J Ӂ* % ݉?|D } d5: eP0 R; {$X' x F @ .ÊB {,WJ uQ ɲRI ;9 Q E琯 6 2fT .DU J ;*c P A\IL Nj! J ۱+ O\ ͔ ] ޒ S J ȧ c%A N ol ՎprU L Zԛe r E2= X D Xg VQeӓ k y P7 U* o m Q I s ,K `) 6\G3t?pgjr m ۛجw luGt f h 9uyP 0D;Uڽ"OXl i f $ ) &|ML 0 Z rm1 [ H XP l P R0 'G=i 2N +0 e 2 ]] 9 VT P O 7 h(F * 癈 ' = Q VZD F,d ߬ ~ T X G[ `le 69C R(!S2! P < 0 x < !1AQ "Raq 02Br #S CTb ? Ζ "]mH5WR 7 k.ۛ ! } Q~ + yԏ z |@ T20 S~ K e k *zF f^2X *( @ 8 r ? C I uI|֓>^Ex LgNU Y+{.R Ѫ τV YT D I 6 2 '8Y2 7'\T P.6 d &˦ @V q i |8 -O Ε ] ʔ U= T L 8= ;6c | !qfF3 a ů& ~$ l} 'NW U s$U k^S V : U#6w + +s &r+n ڐ { @ 29gL u " T Ù M=6 (^ "7 r}=6Yݾ lC u hquymp Ǧ G jhs ǜNl ɻ} o 7 #S6 a w 4 ! OS r D 5 7 % | ?x> L | / nD 6?/8 w # [ ) L 7 +6〼T A T g ! %5 Mm Z /c -{1_Je "| ^$ 'O & ޱմ < H vNqϡQ$ < 6 &Nݛ ֨tǻN (9 n ru~'όN sMG& ,uH Kw *Ī 5@ u6 BԒ i YN * f 0 _ GhKW u lT <nj- 0{ M L~ | /a v\ E = ?1 \ɟuq Ђ Y O a K ޡP q $ H8o Q˼EV ~ k 0 h' L Pp M -M" m^ !6l nմ 쮝C U T . ! :vMǨb h ډ Vc r @~p # !1QAa q ? AL0L x LU 4 d ; x " 16ad0 7.\ߋ 0 = P l v/ " c A Ay A|2pO8"d MV #1] = \ " ˡ ] k v I9 d ۓ & q ) ǐq E ꞅ v "P )q X &Q З non]я u ג./ ; gZ$ M QР 2M ]h ni 0 P $ێ 3CɏGjώy : m c # S_ l@ '_ \m|C 2`K _ 1 cIvGc $? PCQ S+D ? K aײ k Fr b 8 ύ NEدg ĝ U 3 6 #Ik+ v { v i ( ވ ? a e) X xy/*@Q Ǽ Ծ ) $ IWO l c G; !i k{ gOŀ L ('x T rb $ w) R $ & N1E td U3Uȉ1p M"N* (DNy d96.(jQ) X 5 c QɎMy W ? Q *!R > 6=7)Xj 5`J ] e 8%t ! + ' ! 1Q 5 !1 AQaq ё #2 "0BRb ? G t^ ## .l lQ T $ v , ,m 㵜5u bV =sY+ @d { N ! dn O < .- B; _w J t 6;Q Jd. Q c%p{ 1 ,sND dF H I0 Гo X ш e黅X ۢ F :)[ F G X ƹ / w _c MeD ,ʡc c . W D tA $ j@ : ) - #u c1< @ۗ9F ) KJ- hpP] _ x [ q B lb p ʖ w q " LFGd ƶ * s +ډ_Zc " ? % t[I P 6 J ]# =ɺ V v v CGs Gh1 > )6 |e y ? L ӣ m,4 G W Ui ` ] uJVo VDG< SB 6ϏQ @ TiU l y O U 0 kfV ~ ~}S Z @ *WU Ui ## ; s /[ = ! 7}" W N ] ' (L ! ~ y5 g9T̅J kbM' +s :S +B) v @ M j e C f j E 0 Y\Qn z G 1 д~ W o{T 9?` Rm yhsy3 !HAD ] m c1 ~ 2 L S u7x T ;j$ `} 4-> L# vzŏ I L S ֭ T { r jGK C ; b pU= - ` Bs K. S F w4 M q] Z dH S 0 ) tLg
<?php
namespace Elementor\Modules\Components;
use Elementor\Core\Base\Document;
use Elementor\Core\Utils\Api\Error_Builder;
use Elementor\Core\Utils\Api\Response_Builder;
use Elementor\Core\Utils\Collection;
use Elementor\Modules\Components\Documents\Component;
use Elementor\Modules\Components\OverridableProps\Component_Overridable_Props_Parser;
if ( ! defined( 'ABSPATH' ) ) {
exit; // Exit if accessed directly.
}
class Components_REST_API {
const API_NAMESPACE = 'elementor/v1';
const API_BASE = 'components';
const LOCK_DOCUMENT_TYPE_NAME = 'components';
const STYLES_ROUTE = 'styles';
const MAX_COMPONENTS = 100;
private $repository = null;
public function register_hooks() {
add_action( 'rest_api_init', fn() => $this->register_routes() );
}
private function get_repository() {
if ( ! $this->repository ) {
$this->repository = new Components_Repository();
}
return $this->repository;
}
/**
* @return Component_Lock_Manager instance
*/
private function get_component_lock_manager() {
return Component_Lock_Manager::get_instance();
}
private function register_routes() {
register_rest_route( self::API_NAMESPACE, '/' . self::API_BASE, [
[
'methods' => 'GET',
'callback' => fn() => $this->route_wrapper( fn() => $this->get_components() ),
'permission_callback' => fn() => current_user_can( 'edit_posts' ),
],
] );
register_rest_route( self::API_NAMESPACE, '/' . self::API_BASE . '/' . self::STYLES_ROUTE, [
[
'methods' => 'GET',
'callback' => fn() => $this->route_wrapper( fn() => $this->get_styles() ),
'permission_callback' => fn() => current_user_can( 'edit_posts' ),
],
] );
register_rest_route( self::API_NAMESPACE, '/' . self::API_BASE, [
[
'methods' => 'POST',
'callback' => fn( $request ) => $this->route_wrapper( fn() => $this->create_components( $request ) ),
'permission_callback' => fn() => current_user_can( 'manage_options' ),
'args' => [
'status' => [
'type' => 'string',
'enum' => [ Document::STATUS_PUBLISH, Document::STATUS_DRAFT, Document::STATUS_AUTOSAVE ],
'required' => true,
],
'items' => [
'type' => 'array',
'required' => true,
'items' => [
'type' => 'object',
'properties' => [
'uid' => [
'type' => 'string',
'required' => true,
],
'title' => [
'type' => 'string',
'required' => true,
'minLength' => 2,
'maxLength' => 200,
],
'elements' => [
'type' => 'array',
'required' => true,
'items' => [
'type' => 'object',
],
],
'settings' => [
'type' => 'object',
'required' => false,
],
],
],
],
],
],
] );
register_rest_route( self::API_NAMESPACE, '/' . self::API_BASE . '/create-validate', [
[
'methods' => 'POST',
'callback' => fn( $request ) => $this->route_wrapper( fn() => $this->create_validate_components( $request ) ),
'permission_callback' => fn() => current_user_can( 'manage_options' ),
'args' => [
'items' => [
'type' => 'array',
'required' => true,
'items' => [
'type' => 'object',
'properties' => [
'uid' => [
'type' => 'string',
'required' => true,
],
'title' => [
'type' => 'string',
'required' => true,
'minLength' => 2,
'maxLength' => 200,
],
'elements' => [
'type' => 'array',
'required' => true,
'items' => [
'type' => 'object',
],
],
'settings' => [
'type' => 'object',
'required' => false,
],
],
],
],
],
],
] );
register_rest_route( self::API_NAMESPACE, '/' . self::API_BASE . '/overridable-props', [
[
'methods' => 'GET',
'callback' => fn( $request ) => $this->route_wrapper( fn() => $this->get_overridable_props( $request ) ),
'permission_callback' => fn() => current_user_can( 'edit_posts' ),
'args' => [
'componentIds' => [
'type' => 'array',
'items' => [
'type' => 'integer',
],
'required' => true,
'description' => 'The component IDs to get overridable props for',
],
],
],
] );
register_rest_route( self::API_NAMESPACE, '/' . self::API_BASE . '/status', [
[
'methods' => 'PUT',
'callback' => fn( $request ) => $this->route_wrapper( fn() => $this->update_statuses( $request ) ),
'permission_callback' => fn() => current_user_can( 'manage_options' ),
'args' => [
'status' => [
'type' => 'string',
'required' => true,
'enum' => [ Document::STATUS_PUBLISH ],
],
'ids' => [
'type' => 'array',
'required' => true,
'items' => [
'type' => 'number',
'required' => true,
],
],
],
],
] );
register_rest_route( self::API_NAMESPACE, '/' . self::API_BASE . '/lock', [
[
'methods' => 'POST',
'callback' => fn( $request ) => $this->route_wrapper( fn() => $this->lock_component( $request ) ),
'permission_callback' => fn() => current_user_can( 'manage_options' ),
'args' => [
'componentId' => [
'type' => 'number',
'required' => true,
'description' => 'The component ID to unlock',
],
],
],
] );
register_rest_route( self::API_NAMESPACE, '/' . self::API_BASE . '/unlock', [
[
'methods' => 'POST',
'callback' => fn( $request ) => $this->route_wrapper( fn() => $this->unlock_component( $request ) ),
'permission_callback' => fn() => current_user_can( 'manage_options' ),
'args' => [
'componentId' => [
'type' => 'number',
'required' => true,
'description' => 'The component ID to unlock',
],
],
],
] );
register_rest_route( self::API_NAMESPACE, '/' . self::API_BASE . '/lock-status', [
[
'methods' => 'GET',
'callback' => fn( $request ) => $this->route_wrapper( fn() => $this->get_lock_status( $request ) ),
'permission_callback' => fn() => current_user_can( 'manage_options' ),
'args' => [
'componentId' => [
'type' => 'string',
'required' => true,
'description' => 'The component ID to check lock status',
],
],
],
] );
register_rest_route( self::API_NAMESPACE, '/' . self::API_BASE . '/archive', [
[
'methods' => 'POST',
'callback' => fn( $request ) => $this->route_wrapper( fn() => $this->archive_components( $request ) ),
'permission_callback' => fn() => current_user_can( 'manage_options' ),
'args' => [
'componentIds' => [
'type' => 'array',
'items' => [
'type' => 'number',
'required' => true,
],
'required' => true,
'description' => 'The component IDs to archive',
],
'status' => [
'type' => 'string',
'enum' => [ Document::STATUS_PUBLISH, Document::STATUS_DRAFT, Document::STATUS_AUTOSAVE ],
'required' => true,
],
],
],
] );
register_rest_route( self::API_NAMESPACE, '/' . self::API_BASE . '/update-titles', [
[
'methods' => 'POST',
'callback' => fn( $request ) => $this->route_wrapper( fn() => $this->update_components_title( $request ) ),
'permission_callback' => fn() => current_user_can( 'manage_options' ),
'args' => [
'components' => [
'type' => 'array',
'required' => true,
'items' => [
'type' => 'object',
'properties' => [
'componentId' => [
'type' => 'number',
'required' => true,
'description' => 'The component ID to update title',
],
'title' => [
'type' => 'string',
'required' => true,
'description' => 'The new title for the component',
],
],
],
],
'status' => [
'type' => 'string',
'enum' => [ Document::STATUS_PUBLISH, Document::STATUS_DRAFT, Document::STATUS_AUTOSAVE ],
'required' => true,
],
],
],
] );
}
private function get_components() {
$components = $this->get_repository()->all();
$components_list = array_values( $components
->map( fn( $component ) => [
'id' => $component['id'],
'name' => $component['title'],
'uid' => $component['uid'],
'isArchived' => $component['is_archived'] ?? false,
] )
->all() );
return Response_Builder::make( $components_list )->build();
}
private function get_styles() {
$components = $this->get_repository()->all();
$styles = [];
$components->each( function( $component ) use ( &$styles ) {
$styles[ $component['id'] ] = $component['styles'];
} );
return Response_Builder::make( $styles )->build();
}
private function get_overridable_props( \WP_REST_Request $request ) {
$component_ids = $request->get_param( 'componentIds' );
$data = [];
$errors = [];
foreach ( $component_ids as $component_id ) {
$component_id = (int) $component_id;
/** @var Component $document */
$document = $this->get_repository()->get( $component_id );
if ( ! $document ) {
$errors[ $component_id ] = 'component_not_found';
continue;
}
// This is a fix for the case where overridable props in element settings where migrated
// but the overridable props metadata were not aligned with the new origin values.
// In version 4.0.1, we fixed this by running the align_overridable_props_with_elements method after the migration.
$document_version = $document->get_elementor_version();
$overridable_props_migration_fix_version = '4.0.1';
$should_align_overridable_props = version_compare( $document_version, $overridable_props_migration_fix_version, '<=' );
if ( $should_align_overridable_props ) {
$document->align_overridable_props_with_elements();
}
$overridable = $document->get_json_meta( Component::OVERRIDABLE_PROPS_META_KEY );
$data[ $component_id ] = empty( $overridable ) ? null : $overridable;
}
return Response_Builder::make( $data )
->set_meta( [ 'errors' => $errors ] )
->build();
}
private function create_components( \WP_REST_Request $request ) {
if ( ! Components_Access_Controller::can_create() ) {
return $this->get_insufficient_permissions_error( 'create' );
}
$save_status = $request->get_param( 'status' );
$items = Collection::make( $request->get_param( 'items' ) );
$components = $this->get_repository()->all();
$result = Save_Components_Validator::make( $components )->validate( $items );
if ( ! $result['success'] ) {
return Error_Builder::make( 'components_validation_failed' )
->set_status( 422 )
->set_message( 'Validation failed: ' . implode( ', ', $result['messages'] ) )
->build();
}
$circular_result = Circular_Dependency_Validator::make()->validate_new_components( $items );
if ( ! $circular_result['success'] ) {
return Error_Builder::make( 'circular_dependency_detected' )
->set_status( 422 )
->set_message( __( "Can't add this component - components that contain each other can't be nested.", 'elementor' ) )
->set_meta( [ 'caused_by' => $circular_result['messages'] ] )
->build();
}
$non_atomic_result = Non_Atomic_Widget_Validator::make()->validate_items( $items );
if ( ! $non_atomic_result['success'] ) {
return Error_Builder::make( Non_Atomic_Widget_Validator::ERROR_CODE )
->set_status( 422 )
->set_message( __( 'Components require atomic elements only. Remove widgets to create this component.', 'elementor' ) )
->set_meta( [ 'non_atomic_elements' => $non_atomic_result['non_atomic_elements'] ] )
->build();
}
$validation_errors = [];
$created = $items->map_with_keys( function ( $item ) use ( $save_status, &$validation_errors ) {
$title = sanitize_text_field( $item['title'] );
$content = $item['elements'];
$uid = $item['uid'];
try {
$settings = isset( $item['settings'] ) ? $this->parse_settings( $item['settings'] ) : [];
$status = Document::STATUS_AUTOSAVE === $save_status
? Document::STATUS_DRAFT
: $save_status;
$component_id = $this->get_repository()->create( $title, $content, $status, $uid, $settings );
return [ $uid => $component_id ];
} catch ( \Exception $e ) {
$validation_errors[ $uid ] = $e->getMessage();
return [ $uid => null ];
}
} );
if ( ! empty( $validation_errors ) ) {
return Error_Builder::make( 'settings_validation_failed' )
->set_status( 422 )
->set_message( 'Settings validation failed: ' . json_encode( $validation_errors ) )
->build();
}
return Response_Builder::make( $created->all() )
->set_status( 201 )
->build();
}
private function update_statuses( \WP_REST_Request $request ) {
if ( ! Components_Access_Controller::can_publish() ) {
return $this->get_insufficient_permissions_error( 'publish' );
}
$result = Collection::make( $request->get_param( 'ids' ) )
->reduce(
function ( $result, int $component_id ) {
$component = $this->get_repository()->get( $component_id );
if ( ! $component ) {
$result['failed'][] = $component_id;
return $result;
}
$publish_result = $this->get_repository()->publish_component( $component );
$result[ $publish_result ? 'success' : 'failed' ][] = $component_id;
return $result;
},
[
'success' => [],
'failed' => [],
]
);
return Response_Builder::make( $result )->build();
}
private function lock_component( \WP_REST_Request $request ) {
if ( ! Components_Access_Controller::can_lock() ) {
return $this->get_insufficient_permissions_error( 'lock' );
}
$component_id = $request->get_param( 'componentId' );
try {
$success = $this->get_component_lock_manager()->lock( $component_id );
} catch ( \Exception $e ) {
error_log( 'Components REST API lock_component error: ' . $e->getMessage() );
return Error_Builder::make( 'lock_failed' )
->set_status( 500 )
->set_message( __( 'Failed to lock component', 'elementor' ) )
->build();
}
if ( ! $success ) {
return Error_Builder::make( 'lock_failed' )
->set_status( 500 )
->set_message( __( 'Failed to lock component', 'elementor' ) )
->build();
}
return Response_Builder::make( [ 'locked' => $success ] )->build();
}
private function unlock_component( \WP_REST_Request $request ) {
if ( ! Components_Access_Controller::can_lock() ) {
return $this->get_insufficient_permissions_error( 'unlock' );
}
$component_id = $request->get_param( 'componentId' );
try {
$success = $this->get_component_lock_manager()->unlock( $component_id );
} catch ( \Exception $e ) {
error_log( 'Components REST API unlock_component error: ' . $e->getMessage() );
return Error_Builder::make( 'unlock_failed' )
->set_status( 500 )
->set_message( __( 'Failed to unlock component', 'elementor' ) )
->build();
}
if ( ! $success ) {
return Error_Builder::make( 'unlock_failed' )
->set_status( 500 )
->set_message( __( 'Failed to unlock component', 'elementor' ) )
->build();
}
return Response_Builder::make( [ 'unlocked' => $success ] )->build();
}
private function get_lock_status( \WP_REST_Request $request ) {
if ( ! Components_Access_Controller::can_lock() ) {
return $this->get_insufficient_permissions_error( 'lock_status' );
}
$component_id = (int) $request->get_param( 'componentId' );
try {
$lock_manager = $this->get_component_lock_manager();
if ( $lock_manager->is_lock_expired( $component_id ) ) {
$lock_manager->unlock( $component_id );
}
$lock_data = $lock_manager->get_lock_data( $component_id );
$current_user_id = get_current_user_id();
// if current user is the lock user, return true
if ( $lock_data['locked_by'] && $lock_data['locked_by'] === $current_user_id ) {
return Response_Builder::make( [
'is_current_user_allow_to_edit' => true,
'locked_by' => get_user_by( 'id', $lock_data['locked_by'] )->display_name,
] )->build();
}
// if the user is not the lock user, return false
if ( $lock_data['locked_by'] && $lock_data['locked_by'] !== $current_user_id ) {
return Response_Builder::make( [
'is_current_user_allow_to_edit' => false,
'locked_by' => get_user_by( 'id', $lock_data['locked_by'] )->display_name,
] )->build();
}
// if the component is not locked, return true
if ( ! $lock_data['locked_by'] ) {
return Response_Builder::make( [
'is_current_user_allow_to_edit' => true,
'locked_by' => null,
] )->build();
}
} catch ( \Exception $e ) {
error_log( 'Components REST API get_lock_status error: ' . $e->getMessage() );
return Error_Builder::make( 'get_lock_status_failed' )
->set_status( 500 )
->set_message( __( 'Failed to get lock status', 'elementor' ) )
->build();
}
}
private function archive_components( \WP_REST_Request $request ) {
if ( ! Components_Access_Controller::can_delete() ) {
return $this->get_insufficient_permissions_error( 'delete' );
}
$component_ids = $request->get_param( 'componentIds' );
$status = $request->get_param( 'status' );
try {
$result = $this->get_repository()->archive( $component_ids, $status );
} catch ( \Exception $e ) {
error_log( 'Components REST API archive_components error: ' . $e->getMessage() );
return Error_Builder::make( 'archive_failed' )
->set_meta( [ 'error' => $e->getMessage() ] )
->set_status( 500 )
->set_message( __( 'Failed to archive components', 'elementor' ) )
->build();
}
return Response_Builder::make( $result )->build();
}
private function update_components_title( \WP_REST_Request $request ) {
if ( ! Components_Access_Controller::can_rename() ) {
return $this->get_insufficient_permissions_error( 'rename' );
}
$failed_ids = [];
$success_ids = [];
$components = $request->get_param( 'components' );
$status = $request->get_param( 'status' );
foreach ( $components as $component ) {
$is_success = $this->get_repository()->update_title( $component['componentId'], $component['title'], $status );
if ( ! $is_success ) {
$failed_ids[] = $component['componentId'];
continue;
}
$success_ids[] = $component['componentId'];
}
return Response_Builder::make( [
'failedIds' => $failed_ids,
'successIds' => $success_ids,
] )->build();
}
private function create_validate_components( \WP_REST_Request $request ) {
if ( ! Components_Access_Controller::can_create() ) {
return $this->get_insufficient_permissions_error( 'create' );
}
$items = Collection::make( $request->get_param( 'items' ) );
$components = $this->get_repository()->all();
$result = Save_Components_Validator::make( $components )->validate( $items );
if ( ! $result['success'] ) {
return Error_Builder::make( 'components_validation_failed' )
->set_status( 422 )
->set_message( 'Validation failed: ' . implode( ', ', $result['messages'] ) )
->build();
}
$circular_result = Circular_Dependency_Validator::make()->validate_new_components( $items );
if ( ! $circular_result['success'] ) {
return Error_Builder::make( 'circular_dependency_detected' )
->set_status( 422 )
->set_message( __( "Can't add this component - components that contain each other can't be nested.", 'elementor' ) )
->set_meta( [ 'caused_by' => $circular_result['messages'] ] )
->build();
}
$non_atomic_result = Non_Atomic_Widget_Validator::make()->validate_items( $items );
if ( ! $non_atomic_result['success'] ) {
return Error_Builder::make( Non_Atomic_Widget_Validator::ERROR_CODE )
->set_status( 422 )
->set_message( __( 'Components require atomic elements only. Remove widgets to create this component.', 'elementor' ) )
->set_meta( [ 'non_atomic_elements' => $non_atomic_result['non_atomic_elements'] ] )
->build();
}
$validation_errors = $items->map_with_keys( function ( $item ) {
try {
if ( isset( $item['settings'] ) ) {
$this->parse_settings( $item['settings'] );
}
} catch ( \Exception $e ) {
return [ $item['uid'] => $e->getMessage() ];
}
return [ $item['uid'] => null ];
} )
->filter( fn( $value ) => null !== $value );
if ( ! $validation_errors->is_empty() ) {
return Error_Builder::make( 'settings_validation_failed' )
->set_status( 422 )
->set_message( 'Settings validation failed: ' . json_encode( $validation_errors->all() ) )
->build();
}
return Response_Builder::make()
->set_status( 200 )
->build();
}
private function parse_settings( array $settings ): array {
$result = [];
if ( empty( $settings ) ) {
return $result;
}
if ( isset( $settings['overridable_props'] ) ) {
$parser = Component_Overridable_Props_Parser::make();
$overridable_props_result = $parser->parse( $settings['overridable_props'] );
if ( ! $overridable_props_result->is_valid() ) {
throw new \Exception(
esc_html( 'Validation failed for overridable_props: ' . $overridable_props_result->errors()->to_string() )
);
}
$result['overridable_props'] = $overridable_props_result->unwrap();
}
return $result;
}
private function route_wrapper( callable $cb ) {
try {
$response = $cb();
} catch ( \Exception $e ) {
return Error_Builder::make( 'unexpected_error' )
->set_message( __( 'Something went wrong', 'elementor' ) )
->build();
}
return $response;
}
private function get_insufficient_permissions_error( string $action ) {
return Error_Builder::make( 'insufficient_permissions' )
->set_status( 403 )
->set_message( __( 'You do not have permission to perform this action.', 'elementor' ) )
->set_meta( [
'action' => $action,
'tier' => Components_Access_Controller::get_access_tier(),
] )
->build();
}
}