<commit_before>/**
 * Appcelerator Titanium Mobile
 * Copyright (c) 2009-2012 by Appcelerator, Inc. All Rights Reserved.
 * Licensed under the terms of the Apache Public License
 * Please see the LICENSE included with this distribution for details.
 */
package org.appcelerator.titanium.util;

import java.util.HashMap;

import org.appcelerator.kroll.KrollDict;
import org.appcelerator.kroll.KrollFunction;
import org.appcelerator.kroll.common.Log;
import org.appcelerator.kroll.common.TiConfig;
import org.appcelerator.titanium.TiC;
import org.appcelerator.titanium.TiDimension;
import org.appcelerator.titanium.proxy.TiViewProxy;
import org.appcelerator.titanium.view.Ti2DMatrix;
import org.appcelerator.titanium.view.TiAnimation;
import org.appcelerator.titanium.view.TiCompositeLayout;
import org.appcelerator.titanium.view.TiCompositeLayout.LayoutParams;
import org.appcelerator.titanium.view.TiUIView;

import android.graphics.Color;
import android.graphics.Matrix;
import android.graphics.Rect;
import android.graphics.RectF;
import android.graphics.drawable.ColorDrawable;
import android.graphics.drawable.Drawable;
import android.graphics.drawable.TransitionDrawable;
import android.os.Build;
import android.os.Looper;
import android.os.MessageQueue;
import android.view.View;
import android.view.ViewGroup;
import android.view.ViewParent;
import android.view.animation.AlphaAnimation;
import android.view.animation.Animation;
import android.view.animation.AnimationSet;
import android.view.animation.LinearInterpolator;
import android.view.animation.ScaleAnimation;
import android.view.animation.Transformation;
import android.view.animation.TranslateAnimation;


public class TiAnimationBuilder
{
	private static final String LCAT = "TiAnimationBuilder";
	private static final boolean DBG = TiConfig.LOGD;
	
	protected float anchorX;
	protected float anchorY;
	protected Ti2DMatrix tdm = null;
	protected Double delay = null;
	protected Double duration = null;
	protected Double toOpacity = null;
	protected Double fromOpacity = null;
	protected Double repeat = null;
	protected Boolean autoreverse = null;
	protected Integer top = null, bottom = null, left = null, right = null;
	protected Integer centerX = null, centerY = null;
	protected Integer width = null, height = null;
	protected Integer backgroundColor = null;
	
	protected TiAnimation animationProxy;
	protected KrollFunction callback;
	protected boolean relayoutChild = false, applyOpacity = false;
	@SuppressWarnings("rawtypes")
	protected HashMap options;
	protected View view;
	protected TiViewProxy viewProxy;


	public TiAnimationBuilder() 
	{
		anchorX = Ti2DMatrix.DEFAULT_ANCHOR_VALUE;
		anchorY = Ti2DMatrix.DEFAULT_ANCHOR_VALUE;
	}

	@SuppressWarnings({"unchecked","rawtypes"})
	public void applyOptions(HashMap options)
	{
		if (options == null) {
			return;
		}

		if (options.containsKey(TiC.PROPERTY_ANCHOR_POINT)) {
			Object anchorPoint = options.get(TiC.PROPERTY_ANCHOR_POINT);
			if (anchorPoint instanceof HashMap) {
				HashMap point = (HashMap)anchorPoint;
				anchorX = TiConvert.toFloat(point, TiC.PROPERTY_X);
				anchorY = TiConvert.toFloat(point, TiC.PROPERTY_Y);
			} else {
				Log.e(LCAT, "invalid argument type for anchorPoint property. Ignoring");
			}
		}

		if (options.containsKey(TiC.PROPERTY_TRANSFORM)) {
			tdm = (Ti2DMatrix) options.get(TiC.PROPERTY_TRANSFORM);
		}
		if (options.containsKey(TiC.PROPERTY_DELAY)) {
			delay = TiConvert.toDouble(options, TiC.PROPERTY_DELAY);
		}
		if (options.containsKey(TiC.PROPERTY_DURATION)) {
			duration = TiConvert.toDouble(options, TiC.PROPERTY_DURATION);
		}
		if (options.containsKey(TiC.PROPERTY_OPACITY)) {
			toOpacity = TiConvert.toDouble(options, TiC.PROPERTY_OPACITY);
		}
		if (options.containsKey(TiC.PROPERTY_REPEAT)) {
			repeat = TiConvert.toDouble(options, TiC.PROPERTY_REPEAT);
			if (repeat == 0d) {
				// A repeat of 0 is probably non-sensical. Titanium iOS
				// treats it as 1 and so should we.
				repeat = 1d;
			}
		} else {
			repeat = 1d; // Default as indicated in our documentation.
		}
		if (options.containsKey(TiC.PROPERTY_AUTOREVERSE)) {
			autoreverse = TiConvert.toBoolean(options, TiC.PROPERTY_AUTOREVERSE);
		}
		if (options.containsKey(TiC.PROPERTY_TOP)) {
			top = TiConvert.toInt(options, TiC.PROPERTY_TOP);
		}
		if (options.containsKey(TiC.PROPERTY_BOTTOM)) {
			bottom = TiConvert.toInt(options, TiC.PROPERTY_BOTTOM);
		}
		if (options.containsKey(TiC.PROPERTY_LEFT)) {
			left = TiConvert.toInt(options, TiC.PROPERTY_LEFT);
		}
		if (options.containsKey(TiC.PROPERTY_RIGHT)) {
			right = TiConvert.toInt(options, TiC.PROPERTY_RIGHT);
		}
		if (options.containsKey(TiC.PROPERTY_CENTER)) {
			Object centerPoint = options.get(TiC.PROPERTY_CENTER);
			if (centerPoint instanceof HashMap) {
				HashMap center = (HashMap) centerPoint;
				centerX = TiConvert.toInt(center, TiC.PROPERTY_X);
				centerY = TiConvert.toInt(center, TiC.PROPERTY_Y);
				
			} else {
				Log.e(LCAT, "Invalid argument type for center property. Ignoring");
			}
		}
		if (options.containsKey(TiC.PROPERTY_WIDTH)) {
			width = TiConvert.toInt(options, TiC.PROPERTY_WIDTH);
		}
		if (options.containsKey(TiC.PROPERTY_HEIGHT)) {
			height = TiConvert.toInt(options, TiC.PROPERTY_HEIGHT);
		}
		if (options.containsKey(TiC.PROPERTY_BACKGROUND_COLOR)) {
			backgroundColor = TiConvert.toColor(options, TiC.PROPERTY_BACKGROUND_COLOR);
		}
		
		this.options = options;
	}

	public void applyAnimation(TiAnimation anim)
	{
		this.animationProxy = anim;
		applyOptions(anim.getProperties());
	}

	public void setCallback(KrollFunction callback)
	{
		this.callback = callback;
	}

	public AnimationSet render(TiViewProxy viewProxy, View view)
	{
		ViewParent parent = view.getParent();
		int parentWidth = 0;
		int parentHeight = 0;

		if (parent instanceof ViewGroup) {
			ViewGroup group = (ViewGroup) parent;
			parentHeight = group.getMeasuredHeight();
			parentWidth = group.getMeasuredWidth();
		}

		return render(viewProxy, view, view.getLeft(), view.getTop(), view.getMeasuredWidth(), view.getMeasuredHeight(), parentWidth, parentHeight);
	}

	private void addAnimation(AnimationSet animationSet, Animation animation)
	{
		boolean reverse = (autoreverse != null && autoreverse.booleanValue());
		animation.setRepeatMode(reverse ? Animation.REVERSE : Animation.RESTART);

		// We need to reduce the repeat count by 1, since for native Android
		// 1 would mean repeating it once.
		int repeatCount = (repeat == null ? 0 : repeat.intValue() - 1);

		// In Android (native), the repeat count includes reverses. So we
		// need to double-up and add one to the repeat count if we're reversing.
		if (reverse) {
			repeatCount = repeatCount * 2 + 1;
		}

		animation.setRepeatCount(repeatCount);

		animationSet.addAnimation(animation);
	}

	public TiMatrixAnimation createMatrixAnimation(Ti2DMatrix matrix)
	{
		return new TiMatrixAnimation(matrix, anchorX, anchorY);
	}

	public AnimationSet render(TiViewProxy viewProxy, View view, int x, int y, int w, int h, int parentWidth, int parentHeight)
	{
		this.view = view;
		this.viewProxy = viewProxy;
		
		AnimationSet as = new AnimationSet(false);
		AnimationListener animationListener = new AnimationListener();
		
		if (toOpacity != null) {
			if (viewProxy.hasProperty(TiC.PROPERTY_OPACITY)) {
				fromOpacity = TiConvert.toDouble(viewProxy.getProperty(TiC.PROPERTY_OPACITY));

			} else {
				fromOpacity = 1.0 - toOpacity;
			}
			
			Animation animation = new AlphaAnimation(fromOpacity.floatValue(), toOpacity.floatValue());
			applyOpacity = true;
			addAnimation(as, animation);
			animation.setAnimationListener(animationListener);

			TiUIView uiView = viewProxy.peekView();
			if (viewProxy.hasProperty(TiC.PROPERTY_OPACITY) && fromOpacity != null && toOpacity != null
				&& uiView != null) {
				// Initialize the opacity to 1 when we are going to change it in
				// the animation. If the opacity of the view was initialized to
				// 0, the animation doesn't work
				uiView.setOpacity(1);
			}
		}
		
		if (backgroundColor != null) {
			int fromBackgroundColor = 0;
			
			if (viewProxy.hasProperty(TiC.PROPERTY_BACKGROUND_COLOR)) {
				fromBackgroundColor = TiConvert.toColor(TiConvert.toString(viewProxy.getProperty(TiC.PROPERTY_BACKGROUND_COLOR)));
			} else {
				Log.w(LCAT, "Cannot animate view without a backgroundColor. View doesn't have that property. Using #00000000");
				fromBackgroundColor = Color.argb(0,0,0,0);
			}
			Animation a = new TiColorAnimation(view, fromBackgroundColor, backgroundColor);
			addAnimation(as, a);
		}

		if (tdm != null) {
			as.setFillAfter(true);
			as.setFillEnabled(true);

			TiUIView tiView = viewProxy.peekView();

			// For scale animations, rely on the Android-provided ScaleAnimation rather than our
			// TiMatrixAnimation and Operation.
			Animation anim;
			if (tdm.isScaleOperation()) {
				// fromX, toX, fromY, toY, anchorX, anchorY
				float[] params = tdm.getScaleOperationParameters();
				float fromX = params[0];
				float fromY = params[2];

				if (fromX == Ti2DMatrix.VALUE_UNSPECIFIED) {
					if (tiView != null) {
						fromX = tiView.getAnimatedXScale();
					} else {
						fromX = 1.0f; // i.e., regular size.
					}
				}

				if (fromY == Ti2DMatrix.VALUE_UNSPECIFIED) {
					if (tiView != null) {
						fromY = tiView.getAnimatedYScale();
					} else {
						fromY = 1.0f; // i.e., regular size.
					}
				}

				anim = new ScaleAnimation(fromX, params[1], fromY, params[3],
					Animation.RELATIVE_TO_SELF, params[4],
					Animation.RELATIVE_TO_SELF, params[5]);

				// Remember the toX, toY
				if (tiView != null) {
					tiView.setAnimatedXScale(params[1]);
					tiView.setAnimatedYScale(params[3]);
				}

			} else {

				if (tdm.isRotateOperation()) {
					// Make sure we rotate from the right starting position,
					// in case a rotation has already occurred.
					float[] params = tdm.getRotateOperationParameters();
					float fromDegrees = params[0];
					float toDegrees = params[1];

					if (fromDegrees == Ti2DMatrix.VALUE_UNSPECIFIED) {
						fromDegrees = tiView.getAnimatedRotationDegrees();
						tdm.setRotationFromDegrees(fromDegrees);
					}

					// And remember for next time.
					tiView.setAnimatedRotationDegrees(toDegrees);

				}

				anim = new TiMatrixAnimation(tdm, anchorX, anchorY);

			}

			anim.setFillAfter(true);

			if (duration != null) {
				anim.setDuration(duration.longValue());
			}
<commit_msg>TIMOB-9495 Take autoreverse into account when remembering the scale/rotation at end of animation.<commit_after>/**
 * Appcelerator Titanium Mobile
 * Copyright (c) 2009-2012 by Appcelerator, Inc. All Rights Reserved.
 * Licensed under the terms of the Apache Public License
 * Please see the LICENSE included with this distribution for details.
 */
package org.appcelerator.titanium.util;

import java.util.HashMap;

import org.appcelerator.kroll.KrollDict;
import org.appcelerator.kroll.KrollFunction;
import org.appcelerator.kroll.common.Log;
import org.appcelerator.kroll.common.TiConfig;
import org.appcelerator.titanium.TiC;
import org.appcelerator.titanium.TiDimension;
import org.appcelerator.titanium.proxy.TiViewProxy;
import org.appcelerator.titanium.view.Ti2DMatrix;
import org.appcelerator.titanium.view.TiAnimation;
import org.appcelerator.titanium.view.TiCompositeLayout;
import org.appcelerator.titanium.view.TiCompositeLayout.LayoutParams;
import org.appcelerator.titanium.view.TiUIView;

import android.graphics.Color;
import android.graphics.Matrix;
import android.graphics.Rect;
import android.graphics.RectF;
import android.graphics.drawable.ColorDrawable;
import android.graphics.drawable.Drawable;
import android.graphics.drawable.TransitionDrawable;
import android.os.Build;
import android.os.Looper;
import android.os.MessageQueue;
import android.view.View;
import android.view.ViewGroup;
import android.view.ViewParent;
import android.view.animation.AlphaAnimation;
import android.view.animation.Animation;
import android.view.animation.AnimationSet;
import android.view.animation.LinearInterpolator;
import android.view.animation.ScaleAnimation;
import android.view.animation.Transformation;
import android.view.animation.TranslateAnimation;


public class TiAnimationBuilder
{
	private static final String LCAT = "TiAnimationBuilder";
	private static final boolean DBG = TiConfig.LOGD;
	
	protected float anchorX;
	protected float anchorY;
	protected Ti2DMatrix tdm = null;
	protected Double delay = null;
	protected Double duration = null;
	protected Double toOpacity = null;
	protected Double fromOpacity = null;
	protected Double repeat = null;
	protected Boolean autoreverse = null;
	protected Integer top = null, bottom = null, left = null, right = null;
	protected Integer centerX = null, centerY = null;
	protected Integer width = null, height = null;
	protected Integer backgroundColor = null;
	
	protected TiAnimation animationProxy;
	protected KrollFunction callback;
	protected boolean relayoutChild = false, applyOpacity = false;
	@SuppressWarnings("rawtypes")
	protected HashMap options;
	protected View view;
	protected TiViewProxy viewProxy;


	public TiAnimationBuilder() 
	{
		anchorX = Ti2DMatrix.DEFAULT_ANCHOR_VALUE;
		anchorY = Ti2DMatrix.DEFAULT_ANCHOR_VALUE;
	}

	@SuppressWarnings({"unchecked","rawtypes"})
	public void applyOptions(HashMap options)
	{
		if (options == null) {
			return;
		}

		if (options.containsKey(TiC.PROPERTY_ANCHOR_POINT)) {
			Object anchorPoint = options.get(TiC.PROPERTY_ANCHOR_POINT);
			if (anchorPoint instanceof HashMap) {
				HashMap point = (HashMap)anchorPoint;
				anchorX = TiConvert.toFloat(point, TiC.PROPERTY_X);
				anchorY = TiConvert.toFloat(point, TiC.PROPERTY_Y);
			} else {
				Log.e(LCAT, "invalid argument type for anchorPoint property. Ignoring");
			}
		}

		if (options.containsKey(TiC.PROPERTY_TRANSFORM)) {
			tdm = (Ti2DMatrix) options.get(TiC.PROPERTY_TRANSFORM);
		}
		if (options.containsKey(TiC.PROPERTY_DELAY)) {
			delay = TiConvert.toDouble(options, TiC.PROPERTY_DELAY);
		}
		if (options.containsKey(TiC.PROPERTY_DURATION)) {
			duration = TiConvert.toDouble(options, TiC.PROPERTY_DURATION);
		}
		if (options.containsKey(TiC.PROPERTY_OPACITY)) {
			toOpacity = TiConvert.toDouble(options, TiC.PROPERTY_OPACITY);
		}
		if (options.containsKey(TiC.PROPERTY_REPEAT)) {
			repeat = TiConvert.toDouble(options, TiC.PROPERTY_REPEAT);
			if (repeat == 0d) {
				// A repeat of 0 is probably non-sensical. Titanium iOS
				// treats it as 1 and so should we.
				repeat = 1d;
			}
		} else {
			repeat = 1d; // Default as indicated in our documentation.
		}
		if (options.containsKey(TiC.PROPERTY_AUTOREVERSE)) {
			autoreverse = TiConvert.toBoolean(options, TiC.PROPERTY_AUTOREVERSE);
		}
		if (options.containsKey(TiC.PROPERTY_TOP)) {
			top = TiConvert.toInt(options, TiC.PROPERTY_TOP);
		}
		if (options.containsKey(TiC.PROPERTY_BOTTOM)) {
			bottom = TiConvert.toInt(options, TiC.PROPERTY_BOTTOM);
		}
		if (options.containsKey(TiC.PROPERTY_LEFT)) {
			left = TiConvert.toInt(options, TiC.PROPERTY_LEFT);
		}
		if (options.containsKey(TiC.PROPERTY_RIGHT)) {
			right = TiConvert.toInt(options, TiC.PROPERTY_RIGHT);
		}
		if (options.containsKey(TiC.PROPERTY_CENTER)) {
			Object centerPoint = options.get(TiC.PROPERTY_CENTER);
			if (centerPoint instanceof HashMap) {
				HashMap center = (HashMap) centerPoint;
				centerX = TiConvert.toInt(center, TiC.PROPERTY_X);
				centerY = TiConvert.toInt(center, TiC.PROPERTY_Y);
				
			} else {
				Log.e(LCAT, "Invalid argument type for center property. Ignoring");
			}
		}
		if (options.containsKey(TiC.PROPERTY_WIDTH)) {
			width = TiConvert.toInt(options, TiC.PROPERTY_WIDTH);
		}
		if (options.containsKey(TiC.PROPERTY_HEIGHT)) {
			height = TiConvert.toInt(options, TiC.PROPERTY_HEIGHT);
		}
		if (options.containsKey(TiC.PROPERTY_BACKGROUND_COLOR)) {
			backgroundColor = TiConvert.toColor(options, TiC.PROPERTY_BACKGROUND_COLOR);
		}
		
		this.options = options;
	}

	public void applyAnimation(TiAnimation anim)
	{
		this.animationProxy = anim;
		applyOptions(anim.getProperties());
	}

	public void setCallback(KrollFunction callback)
	{
		this.callback = callback;
	}

	public AnimationSet render(TiViewProxy viewProxy, View view)
	{
		ViewParent parent = view.getParent();
		int parentWidth = 0;
		int parentHeight = 0;

		if (parent instanceof ViewGroup) {
			ViewGroup group = (ViewGroup) parent;
			parentHeight = group.getMeasuredHeight();
			parentWidth = group.getMeasuredWidth();
		}

		return render(viewProxy, view, view.getLeft(), view.getTop(), view.getMeasuredWidth(), view.getMeasuredHeight(), parentWidth, parentHeight);
	}

	private void addAnimation(AnimationSet animationSet, Animation animation)
	{
		boolean reverse = (autoreverse != null && autoreverse.booleanValue());
		animation.setRepeatMode(reverse ? Animation.REVERSE : Animation.RESTART);

		// We need to reduce the repeat count by 1, since for native Android
		// 1 would mean repeating it once.
		int repeatCount = (repeat == null ? 0 : repeat.intValue() - 1);

		// In Android (native), the repeat count includes reverses. So we
		// need to double-up and add one to the repeat count if we're reversing.
		if (reverse) {
			repeatCount = repeatCount * 2 + 1;
		}

		animation.setRepeatCount(repeatCount);

		animationSet.addAnimation(animation);
	}

	public TiMatrixAnimation createMatrixAnimation(Ti2DMatrix matrix)
	{
		return new TiMatrixAnimation(matrix, anchorX, anchorY);
	}

	public AnimationSet render(TiViewProxy viewProxy, View view, int x, int y, int w, int h, int parentWidth, int parentHeight)
	{
		this.view = view;
		this.viewProxy = viewProxy;
		
		AnimationSet as = new AnimationSet(false);
		AnimationListener animationListener = new AnimationListener();
		
		if (toOpacity != null) {
			if (viewProxy.hasProperty(TiC.PROPERTY_OPACITY)) {
				fromOpacity = TiConvert.toDouble(viewProxy.getProperty(TiC.PROPERTY_OPACITY));

			} else {
				fromOpacity = 1.0 - toOpacity;
			}
			
			Animation animation = new AlphaAnimation(fromOpacity.floatValue(), toOpacity.floatValue());
			applyOpacity = true;
			addAnimation(as, animation);
			animation.setAnimationListener(animationListener);

			TiUIView uiView = viewProxy.peekView();
			if (viewProxy.hasProperty(TiC.PROPERTY_OPACITY) && fromOpacity != null && toOpacity != null
				&& uiView != null) {
				// Initialize the opacity to 1 when we are going to change it in
				// the animation. If the opacity of the view was initialized to
				// 0, the animation doesn't work
				uiView.setOpacity(1);
			}
		}
		
		if (backgroundColor != null) {
			int fromBackgroundColor = 0;
			
			if (viewProxy.hasProperty(TiC.PROPERTY_BACKGROUND_COLOR)) {
				fromBackgroundColor = TiConvert.toColor(TiConvert.toString(viewProxy.getProperty(TiC.PROPERTY_BACKGROUND_COLOR)));
			} else {
				Log.w(LCAT, "Cannot animate view without a backgroundColor. View doesn't have that property. Using #00000000");
				fromBackgroundColor = Color.argb(0,0,0,0);
			}
			Animation a = new TiColorAnimation(view, fromBackgroundColor, backgroundColor);
			addAnimation(as, a);
		}

		if (tdm != null) {
			as.setFillAfter(true);
			as.setFillEnabled(true);

			TiUIView tiView = viewProxy.peekView();

			// For scale animations, rely on the Android-provided ScaleAnimation rather than our
			// TiMatrixAnimation and Operation.
			Animation anim;
			if (tdm.isScaleOperation()) {
				// fromX, toX, fromY, toY, anchorX, anchorY
				float[] params = tdm.getScaleOperationParameters();
				float fromX = params[0];
				float fromY = params[2];

				if (fromX == Ti2DMatrix.VALUE_UNSPECIFIED) {
					if (tiView != null) {
						fromX = tiView.getAnimatedXScale();
					} else {
						fromX = 1.0f; // i.e., regular size.
					}
				}

				if (fromY == Ti2DMatrix.VALUE_UNSPECIFIED) {
					if (tiView != null) {
						fromY = tiView.getAnimatedYScale();
					} else {
						fromY = 1.0f; // i.e., regular size.
					}
				}

				anim = new ScaleAnimation(fromX, params[1], fromY, params[3],
					Animation.RELATIVE_TO_SELF, params[4],
					Animation.RELATIVE_TO_SELF, params[5]);

				// Remember the toX, toY
				if (tiView != null) {
					float rememberX = params[1];
					float rememberY = params[3];

					// But if autoreverse is in effect, then
					// set back to the fromX, fromY
					if (autoreverse != null && autoreverse.booleanValue()) {
						rememberX = fromX;
						rememberY = fromY;
					}

					tiView.setAnimatedXScale(rememberX);
					tiView.setAnimatedYScale(rememberY);
				}

			} else {

				if (tdm.isRotateOperation()) {
					// Make sure we rotate from the right starting position,
					// in case a rotation has already occurred.
					float[] params = tdm.getRotateOperationParameters();
					float fromDegrees = params[0];
					float toDegrees = params[1];

					if (fromDegrees == Ti2DMatrix.VALUE_UNSPECIFIED) {
						fromDegrees = tiView.getAnimatedRotationDegrees();
						tdm.setRotationFromDegrees(fromDegrees);
					}

					// And remember for next time.
					if (autoreverse == null || !autoreverse.booleanValue()) {
						tiView.setAnimatedRotationDegrees(toDegrees);
					} else {
						// Because the animation will autoreverse, we
						// want to save the original degrees.
						tiView.setAnimatedRotationDegrees(fromDegrees);
					}

				}

				anim = new TiMatrixAnimation(tdm, anchorX, anchorY);

			}

			anim.setFillAfter(true);

			if (duration != null) {
				anim.setDuration(duration.longValue());
			}

{'fraction_non_alphanumeric': 0.10544929964167714, 'fraction_numerical': 0.005956535902089441, 'mean_word_length': 4.132553140673513, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 3, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 2, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '3023907', 'n_tokens_mistral': 7901, 'n_tokens_neox': 6773, 'n_words': 1577}