1 /**************************************************************************** 2 Copyright (c) 2008-2010 Ricardo Quesada 3 Copyright (c) 2011-2012 cocos2d-x.org 4 Copyright (c) 2013-2014 Chukong Technologies Inc. 5 6 http://www.cocos2d-x.org 7 8 Permission is hereby granted, free of charge, to any person obtaining a copy 9 of this software and associated documentation files (the "Software"), to deal 10 in the Software without restriction, including without limitation the rights 11 to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 12 copies of the Software, and to permit persons to whom the Software is 13 furnished to do so, subject to the following conditions: 14 15 The above copyright notice and this permission notice shall be included in 16 all copies or substantial portions of the Software. 17 18 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 19 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 20 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 21 AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 22 LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 23 OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 24 THE SOFTWARE. 25 ****************************************************************************/ 26 27 /** 28 * @constant 29 * @type Number 30 */ 31 cc.INVALID_INDEX = -1; 32 33 /** 34 * PI is the ratio of a circle's circumference to its diameter. 35 * @constant 36 * @type Number 37 */ 38 cc.PI = Math.PI; 39 40 /** 41 * @constant 42 * @type Number 43 */ 44 cc.FLT_MAX = parseFloat('3.402823466e+38F'); 45 46 /** 47 * @constant 48 * @type Number 49 */ 50 cc.FLT_MIN = parseFloat("1.175494351e-38F"); 51 52 /** 53 * @constant 54 * @type Number 55 */ 56 cc.RAD = cc.PI / 180; 57 58 /** 59 * @constant 60 * @type Number 61 */ 62 cc.DEG = 180 / cc.PI; 63 64 /** 65 * maximum unsigned int value 66 * @constant 67 * @type Number 68 */ 69 cc.UINT_MAX = 0xffffffff; 70 71 /** 72 * <p> 73 * simple macro that swaps 2 variables<br/> 74 * modified from c++ macro, you need to pass in the x and y variables names in string, <br/> 75 * and then a reference to the whole object as third variable 76 * </p> 77 * @param {String} x 78 * @param {String} y 79 * @param {Object} ref 80 * @function 81 * @deprecated since v3.0 82 */ 83 cc.swap = function (x, y, ref) { 84 if (cc.isObject(ref) && !cc.isUndefined(ref.x) && !cc.isUndefined(ref.y)) { 85 var tmp = ref[x]; 86 ref[x] = ref[y]; 87 ref[y] = tmp; 88 } else 89 cc.log(cc._LogInfos.swap); 90 }; 91 92 /** 93 * <p> 94 * Linear interpolation between 2 numbers, the ratio sets how much it is biased to each end 95 * </p> 96 * @param {Number} a number A 97 * @param {Number} b number B 98 * @param {Number} r ratio between 0 and 1 99 * @function 100 * @example 101 * cc.lerp(2,10,0.5)//returns 6<br/> 102 * cc.lerp(2,10,0.2)//returns 3.6 103 */ 104 cc.lerp = function (a, b, r) { 105 return a + (b - a) * r; 106 }; 107 108 /** 109 * get a random number from 0 to 0xffffff 110 * @function 111 * @returns {number} 112 */ 113 cc.rand = function () { 114 return Math.random() * 0xffffff; 115 }; 116 117 /** 118 * returns a random float between -1 and 1 119 * @return {Number} 120 * @function 121 */ 122 cc.randomMinus1To1 = function () { 123 return (Math.random() - 0.5) * 2; 124 }; 125 126 /** 127 * returns a random float between 0 and 1 128 * @return {Number} 129 * @function 130 */ 131 cc.random0To1 = Math.random; 132 133 /** 134 * converts degrees to radians 135 * @param {Number} angle 136 * @return {Number} 137 * @function 138 */ 139 cc.degreesToRadians = function (angle) { 140 return angle * cc.RAD; 141 }; 142 143 /** 144 * converts radians to degrees 145 * @param {Number} angle 146 * @return {Number} 147 * @function 148 */ 149 cc.radiansToDegrees = function (angle) { 150 return angle * cc.DEG; 151 }; 152 /** 153 * converts radians to degrees 154 * @param {Number} angle 155 * @return {Number} 156 * @function 157 */ 158 cc.radiansToDegress = function (angle) { 159 cc.log(cc._LogInfos.radiansToDegress); 160 return angle * cc.DEG; 161 }; 162 163 /** 164 * @constant 165 * @type Number 166 */ 167 cc.REPEAT_FOREVER = Number.MAX_VALUE - 1; 168 169 /** 170 * Helpful macro that setups the GL server state, the correct GL program and sets the Model View Projection matrix 171 * @param {cc.Node} node setup node 172 * @function 173 */ 174 cc.nodeDrawSetup = function (node) { 175 //cc.glEnable(node._glServerState); 176 if (node._shaderProgram) { 177 //cc._renderContext.useProgram(node._shaderProgram._programObj); 178 node._shaderProgram.use(); 179 node._shaderProgram.setUniformForModelViewAndProjectionMatrixWithMat4(); 180 } 181 }; 182 183 /** 184 * <p> 185 * GL states that are enabled:<br/> 186 * - GL_TEXTURE_2D<br/> 187 * - GL_VERTEX_ARRAY<br/> 188 * - GL_TEXTURE_COORD_ARRAY<br/> 189 * - GL_COLOR_ARRAY<br/> 190 * </p> 191 * @function 192 */ 193 cc.enableDefaultGLStates = function () { 194 //TODO OPENGL STUFF 195 /* 196 glEnableClientState(GL_VERTEX_ARRAY); 197 glEnableClientState(GL_COLOR_ARRAY); 198 glEnableClientState(GL_TEXTURE_COORD_ARRAY); 199 glEnable(GL_TEXTURE_2D);*/ 200 }; 201 202 /** 203 * <p> 204 * Disable default GL states:<br/> 205 * - GL_TEXTURE_2D<br/> 206 * - GL_TEXTURE_COORD_ARRAY<br/> 207 * - GL_COLOR_ARRAY<br/> 208 * </p> 209 * @function 210 */ 211 cc.disableDefaultGLStates = function () { 212 //TODO OPENGL 213 /* 214 glDisable(GL_TEXTURE_2D); 215 glDisableClientState(GL_COLOR_ARRAY); 216 glDisableClientState(GL_TEXTURE_COORD_ARRAY); 217 glDisableClientState(GL_VERTEX_ARRAY); 218 */ 219 }; 220 221 /** 222 * <p> 223 * Increments the GL Draws counts by one.<br/> 224 * The number of calls per frame are displayed on the screen when the CCDirector's stats are enabled.<br/> 225 * </p> 226 * @param {Number} addNumber 227 * @function 228 */ 229 cc.incrementGLDraws = function (addNumber) { 230 cc.g_NumberOfDraws += addNumber; 231 }; 232 233 /** 234 * @constant 235 * @type Number 236 */ 237 cc.FLT_EPSILON = 0.0000001192092896; 238 239 /** 240 * <p> 241 * On Mac it returns 1;<br/> 242 * On iPhone it returns 2 if RetinaDisplay is On. Otherwise it returns 1 243 * </p> 244 * @return {Number} 245 * @function 246 */ 247 cc.contentScaleFactor = cc.IS_RETINA_DISPLAY_SUPPORTED ? function () { 248 return cc.director.getContentScaleFactor(); 249 } : function () { 250 return 1; 251 }; 252 253 /** 254 * Converts a Point in points to pixels 255 * @param {cc.Point} points 256 * @return {cc.Point} 257 * @function 258 */ 259 cc.pointPointsToPixels = function (points) { 260 var scale = cc.contentScaleFactor(); 261 return cc.p(points.x * scale, points.y * scale); 262 }; 263 264 /** 265 * Converts a Point in pixels to points 266 * @param {cc.Rect} pixels 267 * @return {cc.Point} 268 * @function 269 */ 270 cc.pointPixelsToPoints = function (pixels) { 271 var scale = cc.contentScaleFactor(); 272 return cc.p(pixels.x / scale, pixels.y / scale); 273 }; 274 275 cc._pointPixelsToPointsOut = function(pixels, outPoint){ 276 var scale = cc.contentScaleFactor(); 277 outPoint.x = pixels.x / scale; 278 outPoint.y = pixels.y / scale; 279 }; 280 281 /** 282 * Converts a Size in points to pixels 283 * @param {cc.Size} sizeInPoints 284 * @return {cc.Size} 285 * @function 286 */ 287 cc.sizePointsToPixels = function (sizeInPoints) { 288 var scale = cc.contentScaleFactor(); 289 return cc.size(sizeInPoints.width * scale, sizeInPoints.height * scale); 290 }; 291 292 /** 293 * Converts a size in pixels to points 294 * @param {cc.Size} sizeInPixels 295 * @return {cc.Size} 296 * @function 297 */ 298 cc.sizePixelsToPoints = function (sizeInPixels) { 299 var scale = cc.contentScaleFactor(); 300 return cc.size(sizeInPixels.width / scale, sizeInPixels.height / scale); 301 }; 302 303 cc._sizePixelsToPointsOut = function (sizeInPixels, outSize) { 304 var scale = cc.contentScaleFactor(); 305 outSize.width = sizeInPixels.width / scale; 306 outSize.height = sizeInPixels.height / scale; 307 }; 308 309 /** 310 * Converts a rect in pixels to points 311 * @param {cc.Rect} pixel 312 * @return {cc.Rect} 313 * @function 314 */ 315 cc.rectPixelsToPoints = cc.IS_RETINA_DISPLAY_SUPPORTED ? function (pixel) { 316 var scale = cc.contentScaleFactor(); 317 return cc.rect(pixel.x / scale, pixel.y / scale, 318 pixel.width / scale, pixel.height / scale); 319 } : function (p) { 320 return p; 321 }; 322 323 /** 324 * Converts a rect in points to pixels 325 * @param {cc.Rect} point 326 * @return {cc.Rect} 327 * @function 328 */ 329 cc.rectPointsToPixels = cc.IS_RETINA_DISPLAY_SUPPORTED ? function (point) { 330 var scale = cc.contentScaleFactor(); 331 return cc.rect(point.x * scale, point.y * scale, 332 point.width * scale, point.height * scale); 333 } : function (p) { 334 return p; 335 }; 336 337 //some gl constant variable 338 /** 339 * @constant 340 * @type Number 341 */ 342 cc.ONE = 1; 343 344 /** 345 * @constant 346 * @type Number 347 */ 348 cc.ZERO = 0; 349 350 /** 351 * @constant 352 * @type Number 353 */ 354 cc.SRC_ALPHA = 0x0302; 355 356 /** 357 * @constant 358 * @type Number 359 */ 360 cc.SRC_ALPHA_SATURATE = 0x308; 361 362 /** 363 * @constant 364 * @type Number 365 */ 366 cc.SRC_COLOR = 0x300; 367 368 /** 369 * @constant 370 * @type Number 371 */ 372 cc.DST_ALPHA = 0x304; 373 374 /** 375 * @constant 376 * @type Number 377 */ 378 cc.DST_COLOR = 0x306; 379 380 /** 381 * @constant 382 * @type Number 383 */ 384 cc.ONE_MINUS_SRC_ALPHA = 0x0303; 385 386 /** 387 * @constant 388 * @type Number 389 */ 390 cc.ONE_MINUS_SRC_COLOR = 0x301; 391 392 /** 393 * @constant 394 * @type Number 395 */ 396 cc.ONE_MINUS_DST_ALPHA = 0x305; 397 398 /** 399 * @constant 400 * @type Number 401 */ 402 cc.ONE_MINUS_DST_COLOR = 0x0307; 403 404 /** 405 * @constant 406 * @type Number 407 */ 408 cc.ONE_MINUS_CONSTANT_ALPHA = 0x8004; 409 410 /** 411 * @constant 412 * @type Number 413 */ 414 cc.ONE_MINUS_CONSTANT_COLOR = 0x8002; 415 416 /** 417 * the constant variable equals gl.LINEAR for texture 418 * @constant 419 * @type Number 420 */ 421 cc.LINEAR = 0x2601; 422 423 /** 424 * the constant variable equals gl.REPEAT for texture 425 * @constant 426 * @type Number 427 */ 428 cc.REPEAT = 0x2901; 429 430 /** 431 * the constant variable equals gl.CLAMP_TO_EDGE for texture 432 * @constant 433 * @type Number 434 */ 435 cc.CLAMP_TO_EDGE = 0x812f; 436 437 /** 438 * the constant variable equals gl.MIRRORED_REPEAT for texture 439 * @constant 440 * @type Number 441 */ 442 cc.MIRRORED_REPEAT = 0x8370; 443 444 /** 445 * default gl blend src function. Compatible with premultiplied alpha images. 446 * @constant 447 * @name cc.BLEND_SRC 448 * @type Number 449 */ 450 cc.BLEND_SRC = cc.SRC_ALPHA; 451 cc.game.addEventListener(cc.game.EVENT_RENDERER_INITED, function () { 452 if (cc._renderType === cc.game.RENDER_TYPE_WEBGL 453 && cc.OPTIMIZE_BLEND_FUNC_FOR_PREMULTIPLIED_ALPHA) { 454 cc.BLEND_SRC = cc.ONE; 455 } 456 }); 457 458 /** 459 * default gl blend dst function. Compatible with premultiplied alpha images. 460 * @constant 461 * @type Number 462 */ 463 cc.BLEND_DST = cc.ONE_MINUS_SRC_ALPHA; 464 465 /** 466 * Check webgl error.Error will be shown in console if exists. 467 * @function 468 */ 469 cc.checkGLErrorDebug = function () { 470 if (cc.renderMode === cc.game.RENDER_TYPE_WEBGL) { 471 var _error = cc._renderContext.getError(); 472 if (_error) { 473 cc.log(cc._LogInfos.checkGLErrorDebug, _error); 474 } 475 } 476 }; 477 478 //Possible device orientations 479 /** 480 * Device oriented vertically, home button on the bottom (UIDeviceOrientationPortrait) 481 * @constant 482 * @type Number 483 */ 484 cc.ORIENTATION_PORTRAIT = 1; 485 486 /** 487 * Device oriented horizontally, home button on the right (UIDeviceOrientationLandscapeLeft) 488 * @constant 489 * @type Number 490 */ 491 cc.ORIENTATION_LANDSCAPE = 2; 492 493 /** 494 * Device oriented vertically, home button on the top (UIDeviceOrientationPortraitUpsideDown) 495 * @constant 496 * @type Number 497 */ 498 cc.ORIENTATION_AUTO = 3; 499 500 501 // ------------------- vertex attrib flags ----------------------------- 502 /** 503 * @constant 504 * @type {Number} 505 */ 506 cc.VERTEX_ATTRIB_FLAG_NONE = 0; 507 /** 508 * @constant 509 * @type {Number} 510 */ 511 cc.VERTEX_ATTRIB_FLAG_POSITION = 1 << 0; 512 /** 513 * @constant 514 * @type {Number} 515 */ 516 cc.VERTEX_ATTRIB_FLAG_COLOR = 1 << 1; 517 /** 518 * @constant 519 * @type {Number} 520 */ 521 cc.VERTEX_ATTRIB_FLAG_TEX_COORDS = 1 << 2; 522 /** 523 * @constant 524 * @type {Number} 525 */ 526 cc.VERTEX_ATTRIB_FLAG_POS_COLOR_TEX = ( cc.VERTEX_ATTRIB_FLAG_POSITION | cc.VERTEX_ATTRIB_FLAG_COLOR | cc.VERTEX_ATTRIB_FLAG_TEX_COORDS ); 527 528 /** 529 * GL server side states 530 * @constant 531 * @type {Number} 532 */ 533 cc.GL_ALL = 0; 534 535 //-------------Vertex Attributes----------- 536 /** 537 * @constant 538 * @type {Number} 539 */ 540 cc.VERTEX_ATTRIB_POSITION = 0; 541 /** 542 * @constant 543 * @type {Number} 544 */ 545 cc.VERTEX_ATTRIB_COLOR = 1; 546 /** 547 * @constant 548 * @type {Number} 549 */ 550 cc.VERTEX_ATTRIB_TEX_COORDS = 2; 551 /** 552 * @constant 553 * @type {Number} 554 */ 555 cc.VERTEX_ATTRIB_MAX = 7; 556 557 //------------Uniforms------------------ 558 /** 559 * @constant 560 * @type {Number} 561 */ 562 cc.UNIFORM_PMATRIX = 0; 563 /** 564 * @constant 565 * @type {Number} 566 */ 567 cc.UNIFORM_MVMATRIX = 1; 568 /** 569 * @constant 570 * @type {Number} 571 */ 572 cc.UNIFORM_MVPMATRIX = 2; 573 /** 574 * @constant 575 * @type {Number} 576 */ 577 cc.UNIFORM_TIME = 3; 578 /** 579 * @constant 580 * @type {Number} 581 */ 582 cc.UNIFORM_SINTIME = 4; 583 /** 584 * @constant 585 * @type {Number} 586 */ 587 cc.UNIFORM_COSTIME = 5; 588 /** 589 * @constant 590 * @type {Number} 591 */ 592 cc.UNIFORM_RANDOM01 = 6; 593 /** 594 * @constant 595 * @type {Number} 596 */ 597 cc.UNIFORM_SAMPLER = 7; 598 /** 599 * @constant 600 * @type {Number} 601 */ 602 cc.UNIFORM_MAX = 8; 603 604 //------------Shader Name--------------- 605 /** 606 * @constant 607 * @type {String} 608 */ 609 cc.SHADER_POSITION_TEXTURECOLOR = "ShaderPositionTextureColor"; 610 /** 611 * @constant 612 * @type {String} 613 */ 614 cc.SHADER_SPRITE_POSITION_TEXTURECOLOR = "ShaderSpritePositionTextureColor"; 615 /** 616 * @constant 617 * @type {String} 618 */ 619 cc.SHADER_POSITION_TEXTURECOLORALPHATEST = "ShaderPositionTextureColorAlphaTest"; 620 /** 621 * @constant 622 * @type {String} 623 */ 624 cc.SHADER_SPRITE_POSITION_TEXTURECOLORALPHATEST = "ShaderSpritePositionTextureColorAlphaTest"; 625 /** 626 * @constant 627 * @type {String} 628 */ 629 cc.SHADER_POSITION_COLOR = "ShaderPositionColor"; 630 /** 631 * @constant 632 * @type {String} 633 */ 634 cc.SHADER_SPRITE_POSITION_COLOR = "ShaderSpritePositionColor"; 635 /** 636 * @constant 637 * @type {String} 638 */ 639 cc.SHADER_POSITION_TEXTURE = "ShaderPositionTexture"; 640 /** 641 * @constant 642 * @type {String} 643 */ 644 cc.SHADER_POSITION_TEXTURE_UCOLOR = "ShaderPositionTexture_uColor"; 645 /** 646 * @constant 647 * @type {String} 648 */ 649 cc.SHADER_POSITION_TEXTUREA8COLOR = "ShaderPositionTextureA8Color"; 650 /** 651 * @constant 652 * @type {String} 653 */ 654 cc.SHADER_POSITION_UCOLOR = "ShaderPosition_uColor"; 655 /** 656 * @constant 657 * @type {String} 658 */ 659 cc.SHADER_POSITION_LENGTHTEXTURECOLOR = "ShaderPositionLengthTextureColor"; 660 661 //------------uniform names---------------- 662 /** 663 * @constant 664 * @type {String} 665 */ 666 cc.UNIFORM_PMATRIX_S = "CC_PMatrix"; 667 /** 668 * @constant 669 * @type {String} 670 */ 671 cc.UNIFORM_MVMATRIX_S = "CC_MVMatrix"; 672 /** 673 * @constant 674 * @type {String} 675 */ 676 cc.UNIFORM_MVPMATRIX_S = "CC_MVPMatrix"; 677 /** 678 * @constant 679 * @type {String} 680 */ 681 cc.UNIFORM_TIME_S = "CC_Time"; 682 /** 683 * @constant 684 * @type {String} 685 */ 686 cc.UNIFORM_SINTIME_S = "CC_SinTime"; 687 /** 688 * @constant 689 * @type {String} 690 */ 691 cc.UNIFORM_COSTIME_S = "CC_CosTime"; 692 /** 693 * @constant 694 * @type {String} 695 */ 696 cc.UNIFORM_RANDOM01_S = "CC_Random01"; 697 /** 698 * @constant 699 * @type {String} 700 */ 701 cc.UNIFORM_SAMPLER_S = "CC_Texture0"; 702 /** 703 * @constant 704 * @type {String} 705 */ 706 cc.UNIFORM_ALPHA_TEST_VALUE_S = "CC_alpha_value"; 707 708 //------------Attribute names-------------- 709 /** 710 * @constant 711 * @type {String} 712 */ 713 cc.ATTRIBUTE_NAME_COLOR = "a_color"; 714 /** 715 * @constant 716 * @type {String} 717 */ 718 cc.ATTRIBUTE_NAME_POSITION = "a_position"; 719 /** 720 * @constant 721 * @type {String} 722 */ 723 cc.ATTRIBUTE_NAME_TEX_COORD = "a_texCoord"; 724 /** 725 * @constant 726 * @type {String} 727 */ 728 cc.ATTRIBUTE_NAME_MVMAT = "a_mvMatrix"; 729 730 731 /** 732 * default size for font size 733 * @constant 734 * @type Number 735 */ 736 cc.ITEM_SIZE = 32; 737 738 /** 739 * default tag for current item 740 * @constant 741 * @type Number 742 */ 743 cc.CURRENT_ITEM = 0xc0c05001; 744 /** 745 * default tag for zoom action tag 746 * @constant 747 * @type Number 748 */ 749 cc.ZOOM_ACTION_TAG = 0xc0c05002; 750 /** 751 * default tag for normal 752 * @constant 753 * @type Number 754 */ 755 cc.NORMAL_TAG = 8801; 756 757 /** 758 * default selected tag 759 * @constant 760 * @type Number 761 */ 762 cc.SELECTED_TAG = 8802; 763 764 /** 765 * default disabled tag 766 * @constant 767 * @type Number 768 */ 769 cc.DISABLE_TAG = 8803; 770 771 772 // Array utils 773 774 /** 775 * Verify Array's Type 776 * @param {Array} arr 777 * @param {function} type 778 * @return {Boolean} 779 * @function 780 */ 781 cc.arrayVerifyType = function (arr, type) { 782 if (arr && arr.length > 0) { 783 for (var i = 0; i < arr.length; i++) { 784 if (!(arr[i] instanceof type)) { 785 cc.log("element type is wrong!"); 786 return false; 787 } 788 } 789 } 790 return true; 791 }; 792 793 /** 794 * Searches for the first occurrence of object and removes it. If object is not found the function has no effect. 795 * @function 796 * @param {Array} arr Source Array 797 * @param {*} delObj remove object 798 */ 799 cc.arrayRemoveObject = function (arr, delObj) { 800 for (var i = 0, l = arr.length; i < l; i++) { 801 if (arr[i] === delObj) { 802 arr.splice(i, 1); 803 break; 804 } 805 } 806 }; 807 808 /** 809 * Removes from arr all values in minusArr. For each Value in minusArr, the first matching instance in arr will be removed. 810 * @function 811 * @param {Array} arr Source Array 812 * @param {Array} minusArr minus Array 813 */ 814 cc.arrayRemoveArray = function (arr, minusArr) { 815 for (var i = 0, l = minusArr.length; i < l; i++) { 816 cc.arrayRemoveObject(arr, minusArr[i]); 817 } 818 }; 819 820 /** 821 * Inserts some objects at index 822 * @function 823 * @param {Array} arr 824 * @param {Array} addObjs 825 * @param {Number} index 826 * @return {Array} 827 */ 828 cc.arrayAppendObjectsToIndex = function(arr, addObjs,index){ 829 arr.splice.apply(arr, [index, 0].concat(addObjs)); 830 return arr; 831 }; 832 833 /** 834 * Copy an array's item to a new array (its performance is better than Array.slice) 835 * @param {Array} arr 836 * @return {Array} 837 */ 838 cc.copyArray = function(arr){ 839 var i, len = arr.length, arr_clone = new Array(len); 840 for (i = 0; i < len; i += 1) 841 arr_clone[i] = arr[i]; 842 return arr_clone; 843 }; 844