You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@ambari.apache.org by tb...@apache.org on 2014/05/02 18:24:48 UTC

[1/7] AMBARI-5616 - Ambari Views: Pig view (Roman Rader via tbeerbower)

Repository: ambari
Updated Branches:
  refs/heads/trunk 75505c635 -> 5eb222143


http://git-wip-us.apache.org/repos/asf/ambari/blob/5eb22214/contrib/views/pig/src/test/java/org/apache/ambari/view/pig/test/HelpTest.java
----------------------------------------------------------------------
diff --git a/contrib/views/pig/src/test/java/org/apache/ambari/view/pig/test/HelpTest.java b/contrib/views/pig/src/test/java/org/apache/ambari/view/pig/test/HelpTest.java
new file mode 100644
index 0000000..5d633dc
--- /dev/null
+++ b/contrib/views/pig/src/test/java/org/apache/ambari/view/pig/test/HelpTest.java
@@ -0,0 +1,59 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.ambari.view.pig.test;
+
+import org.apache.ambari.view.pig.HDFSTest;
+import org.apache.ambari.view.pig.resources.files.FileService;
+import org.apache.ambari.view.pig.services.HelpService;
+import org.json.simple.JSONObject;
+import org.junit.*;
+
+import javax.ws.rs.core.Response;
+
+public class HelpTest extends HDFSTest {
+    private HelpService helpService;
+
+    @Override
+    @Before
+    public void setUp() throws Exception {
+        super.setUp();
+        helpService = new HelpService(context, handler);
+    }
+
+    @BeforeClass
+    public static void startUp() throws Exception {
+        HDFSTest.startUp(); // super
+    }
+
+    @AfterClass
+    public static void shutDown() throws Exception {
+        HDFSTest.shutDown(); // super
+        FileService.setHdfsApi(null); //cleanup API connection
+    }
+
+    @Test
+    public void configTest() {
+        Response response = helpService.config();
+        Assert.assertEquals(200, response.getStatus());
+
+        JSONObject obj = (JSONObject)response.getEntity();
+        Assert.assertTrue(obj.containsKey("dataworker.defaultFs"));
+        Assert.assertEquals(hdfsURI, obj.get("dataworker.defaultFs"));
+    }
+}

http://git-wip-us.apache.org/repos/asf/ambari/blob/5eb22214/contrib/views/pig/src/test/java/org/apache/ambari/view/pig/test/JobTest.java
----------------------------------------------------------------------
diff --git a/contrib/views/pig/src/test/java/org/apache/ambari/view/pig/test/JobTest.java b/contrib/views/pig/src/test/java/org/apache/ambari/view/pig/test/JobTest.java
new file mode 100644
index 0000000..a8a8c34
--- /dev/null
+++ b/contrib/views/pig/src/test/java/org/apache/ambari/view/pig/test/JobTest.java
@@ -0,0 +1,410 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.ambari.view.pig.test;
+
+import org.apache.ambari.view.pig.BasePigTest;
+import org.apache.ambari.view.pig.resources.jobs.JobService;
+import org.apache.ambari.view.pig.resources.jobs.models.PigJob;
+import org.apache.ambari.view.pig.templeton.client.TempletonApi;
+import org.apache.ambari.view.pig.utils.HdfsApi;
+import org.apache.hadoop.fs.FSDataOutputStream;
+import org.json.simple.JSONObject;
+import org.junit.*;
+
+import javax.servlet.http.HttpServletResponse;
+import javax.ws.rs.core.Response;
+import javax.ws.rs.core.UriBuilder;
+import javax.ws.rs.core.UriInfo;
+import java.io.*;
+import java.net.URI;
+import java.util.HashMap;
+
+import static org.easymock.EasyMock.*;
+
+public class JobTest extends BasePigTest {
+    private JobService jobService;
+
+    @Override
+    @Before
+    public void setUp() throws Exception {
+        super.setUp();
+        jobService = getService(JobService.class, handler, context);
+    }
+
+    @Override
+    @After
+    public void tearDown() throws Exception {
+        super.tearDown();
+        jobService.getResourceManager().setTempletonApi(null);
+        JobService.setHdfsApi(null);
+    }
+
+    private Response doCreateJob(String title, String pigScript, String templetonArguments) {
+        return doCreateJob(title, pigScript, templetonArguments, null);
+    }
+
+    private Response doCreateJob(String title, String pigScript, String templetonArguments, String forcedContent) {
+        JobService.PigJobRequest request = new JobService.PigJobRequest();
+        request.job = new PigJob();
+        request.job.setTitle(title);
+        request.job.setPigScript(pigScript);
+        request.job.setTempletonArguments(templetonArguments);
+        request.job.setForcedContent(forcedContent);
+
+        UriInfo uriInfo = createNiceMock(UriInfo.class);
+        URI uri = UriBuilder.fromUri("http://host/a/b").build();
+        expect(uriInfo.getAbsolutePath()).andReturn(uri);
+
+        HttpServletResponse resp_obj = createStrictMock(HttpServletResponse.class);
+
+        resp_obj.setHeader(eq("Location"), anyString());
+
+        replay(uriInfo, resp_obj);
+        return jobService.runJob(request, resp_obj, uriInfo);
+    }
+
+    @Test
+    public void testSubmitJob() throws Exception {
+        HdfsApi hdfsApi = createNiceMock(HdfsApi.class);
+        expect(hdfsApi.copy(eq("/tmp/script.pig"), startsWith("/tmp/.pigjobs/"))).andReturn(true);
+
+        ByteArrayOutputStream do_stream = new ByteArrayOutputStream();
+
+        FSDataOutputStream stream = new FSDataOutputStream(do_stream);
+        expect(hdfsApi.create(anyString(), eq(true))).andReturn(stream);
+        replay(hdfsApi);
+        JobService.setHdfsApi(hdfsApi);
+
+        TempletonApi api = createNiceMock(TempletonApi.class);
+        jobService.getResourceManager().setTempletonApi(api);
+        TempletonApi.JobData data = api.new JobData();
+        expect(api.runPigQuery((File) anyObject(), anyString(), eq("-useHCatalog"))).andReturn(data);
+        replay(api);
+
+        Response response = doCreateJob("Test", "/tmp/script.pig", "-useHCatalog");
+
+        Assert.assertEquals("-useHCatalog", do_stream.toString());
+        Assert.assertEquals(201, response.getStatus());
+
+        JSONObject obj = (JSONObject)response.getEntity();
+        Assert.assertTrue(obj.containsKey("job"));
+        Assert.assertNotNull(((PigJob) obj.get("job")).getId());
+        Assert.assertFalse(((PigJob) obj.get("job")).getId().isEmpty());
+        Assert.assertTrue(((PigJob) obj.get("job")).getStatusDir().startsWith("/tmp/.pigjobs/admin/test"));
+
+        PigJob job = ((PigJob) obj.get("job"));
+        Assert.assertEquals(PigJob.Status.SUBMITTED, job.getStatus());
+        Assert.assertTrue(job.isInProgress());
+    }
+
+    @Test
+    public void testSubmitJobNoArguments() throws Exception {
+        HdfsApi hdfsApi = createNiceMock(HdfsApi.class);
+        expect(hdfsApi.copy(eq("/tmp/script.pig"), startsWith("/tmp/.pigjobs/"))).andReturn(true);
+
+        ByteArrayOutputStream do_stream = new ByteArrayOutputStream();
+
+        FSDataOutputStream stream = new FSDataOutputStream(do_stream);
+        expect(hdfsApi.create(anyString(), eq(true))).andReturn(stream);
+        replay(hdfsApi);
+        JobService.setHdfsApi(hdfsApi);
+
+        TempletonApi api = createNiceMock(TempletonApi.class);
+        jobService.getResourceManager().setTempletonApi(api);
+        TempletonApi.JobData data = api.new JobData();
+        expect(api.runPigQuery((File) anyObject(), anyString(), (String) isNull())).andReturn(data);
+        replay(api);
+
+        Response response = doCreateJob("Test", "/tmp/script.pig", null);
+
+        Assert.assertEquals("", do_stream.toString());
+        Assert.assertEquals(201, response.getStatus());
+
+        JSONObject obj = (JSONObject)response.getEntity();
+        Assert.assertTrue(obj.containsKey("job"));
+        Assert.assertNotNull(((PigJob) obj.get("job")).getId());
+        Assert.assertFalse(((PigJob) obj.get("job")).getId().isEmpty());
+        Assert.assertTrue(((PigJob) obj.get("job")).getStatusDir().startsWith("/tmp/.pigjobs/admin/test"));
+
+        PigJob job = ((PigJob) obj.get("job"));
+        Assert.assertEquals(PigJob.Status.SUBMITTED, job.getStatus());
+        Assert.assertTrue(job.isInProgress());
+    }
+
+    @Test
+    public void testSubmitJobNoFile() throws Exception {
+        HdfsApi hdfsApi = createNiceMock(HdfsApi.class);
+        expect(hdfsApi.copy(eq("/tmp/script.pig"), startsWith("/tmp/.pigjobs/"))).andReturn(true);
+
+        ByteArrayOutputStream do_stream = new ByteArrayOutputStream();
+
+        FSDataOutputStream stream = new FSDataOutputStream(do_stream);
+        expect(hdfsApi.create(anyString(), eq(true))).andReturn(stream);
+        replay(hdfsApi);
+        JobService.setHdfsApi(hdfsApi);
+
+        TempletonApi api = createNiceMock(TempletonApi.class);
+        jobService.getResourceManager().setTempletonApi(api);
+        TempletonApi.JobData data = api.new JobData();
+        expect(api.runPigQuery((File) anyObject(), anyString(), eq("-useHCatalog"))).andReturn(data);
+        replay(api);
+
+        Response response = doCreateJob("Test", null, "-useHCatalog");
+        Assert.assertEquals(400, response.getStatus());
+        JSONObject obj = (JSONObject)response.getEntity();
+        Assert.assertTrue(((String)obj.get("message")).contains("No pigScript file or forcedContent specifed;"));
+    }
+
+    @Test
+    public void testSubmitJobForcedContent() throws Exception {
+        HdfsApi hdfsApi = createNiceMock(HdfsApi.class);
+
+        ByteArrayOutputStream baScriptStream = new ByteArrayOutputStream();
+        ByteArrayOutputStream baTempletonArgsStream = new ByteArrayOutputStream();
+
+        FSDataOutputStream scriptStream = new FSDataOutputStream(baScriptStream);
+        FSDataOutputStream templetonArgsStream = new FSDataOutputStream(baTempletonArgsStream);
+        expect(hdfsApi.create(endsWith("script.pig"), eq(true))).andReturn(scriptStream);
+        expect(hdfsApi.create(endsWith("params"), eq(true))).andReturn(templetonArgsStream);
+        replay(hdfsApi);
+        JobService.setHdfsApi(hdfsApi);
+
+        TempletonApi api = createNiceMock(TempletonApi.class);
+        jobService.getResourceManager().setTempletonApi(api);
+        TempletonApi.JobData data = api.new JobData();
+        expect(api.runPigQuery((File) anyObject(), anyString(), eq("-useHCatalog"))).andReturn(data);
+        replay(api);
+
+        Response response = doCreateJob("Test", null, "-useHCatalog", "pwd");  // with forcedContent
+        Assert.assertEquals(201, response.getStatus());
+        Assert.assertEquals("-useHCatalog", baTempletonArgsStream.toString());
+        Assert.assertEquals("pwd", baScriptStream.toString());
+    }
+
+    @Test
+    public void testSubmitJobNoTitle() throws Exception {
+        HdfsApi hdfsApi = createNiceMock(HdfsApi.class);
+        expect(hdfsApi.copy(eq("/tmp/script.pig"), startsWith("/tmp/.pigjobs/"))).andReturn(true);
+
+        ByteArrayOutputStream do_stream = new ByteArrayOutputStream();
+
+        FSDataOutputStream stream = new FSDataOutputStream(do_stream);
+        expect(hdfsApi.create(anyString(), eq(true))).andReturn(stream);
+        replay(hdfsApi);
+        JobService.setHdfsApi(hdfsApi);
+
+        TempletonApi api = createNiceMock(TempletonApi.class);
+        jobService.getResourceManager().setTempletonApi(api);
+        TempletonApi.JobData data = api.new JobData();
+        expect(api.runPigQuery((File) anyObject(), anyString(), eq("-useHCatalog"))).andReturn(data);
+        replay(api);
+
+        Response response = doCreateJob(null, "/tmp/1.pig", "-useHCatalog");
+        Assert.assertEquals(400, response.getStatus());
+        JSONObject obj = (JSONObject)response.getEntity();
+        Assert.assertTrue(((String)obj.get("message")).contains("No title specifed"));
+    }
+
+    @Test
+    public void testSubmitJobFailed() throws Exception {
+        HdfsApi hdfsApi = createNiceMock(HdfsApi.class);
+        expect(hdfsApi.copy(eq("/tmp/script.pig"), startsWith("/tmp/.pigjobs/"))).andReturn(false);
+
+        ByteArrayOutputStream do_stream = new ByteArrayOutputStream();
+
+        FSDataOutputStream stream = new FSDataOutputStream(do_stream);
+        expect(hdfsApi.create(anyString(), eq(true))).andReturn(stream);
+        replay(hdfsApi);
+        JobService.setHdfsApi(hdfsApi);
+
+        TempletonApi api = createNiceMock(TempletonApi.class);
+        jobService.getResourceManager().setTempletonApi(api);
+        TempletonApi.JobData data = api.new JobData();
+        expect(api.runPigQuery((File) anyObject(), anyString(), eq("-useHCatalog"))).andReturn(data);
+        replay(api);
+
+        Response response = doCreateJob("Test", "/tmp/script.pig", "-useHCatalog");
+        Assert.assertEquals(500, response.getStatus());
+        JSONObject obj = (JSONObject)response.getEntity();
+        Assert.assertTrue(((String)obj.get("message")).contains("Can't copy"));
+    }
+
+    @Test
+    public void testSubmitJobTempletonError() throws Exception {
+        HdfsApi hdfsApi = createNiceMock(HdfsApi.class);
+        expect(hdfsApi.copy(eq("/tmp/script.pig"), startsWith("/tmp/.pigjobs/"))).andReturn(true);
+
+        ByteArrayOutputStream do_stream = new ByteArrayOutputStream();
+
+        FSDataOutputStream stream = new FSDataOutputStream(do_stream);
+        expect(hdfsApi.create(anyString(), eq(true))).andReturn(stream);
+        replay(hdfsApi);
+        JobService.setHdfsApi(hdfsApi);
+
+        TempletonApi api = createNiceMock(TempletonApi.class);
+        jobService.getResourceManager().setTempletonApi(api);
+        TempletonApi.JobData data = api.new JobData();
+        // Templeton returns 500 e.g.
+        expect(api.runPigQuery((File) anyObject(), anyString(), eq("-useHCatalog"))).andThrow(new IOException());
+        replay(api);
+
+        Response response = doCreateJob("Test", "/tmp/script.pig", "-useHCatalog");
+        Assert.assertEquals(500, response.getStatus());
+        JSONObject obj = (JSONObject)response.getEntity();
+        Assert.assertTrue(((String) obj.get("message")).contains("Templeton"));
+    }
+
+    @Test
+    public void testKillJob() throws Exception {
+        HdfsApi hdfsApi = createNiceMock(HdfsApi.class);
+        expect(hdfsApi.copy(eq("/tmp/script.pig"), startsWith("/tmp/.pigjobs/"))).andReturn(true);
+
+        ByteArrayOutputStream do_stream = new ByteArrayOutputStream();
+
+        FSDataOutputStream stream = new FSDataOutputStream(do_stream);
+        expect(hdfsApi.create(anyString(), eq(true))).andReturn(stream);
+        replay(hdfsApi);
+        JobService.setHdfsApi(hdfsApi);
+
+        TempletonApi api = createStrictMock(TempletonApi.class);
+        jobService.getResourceManager().setTempletonApi(api);
+        TempletonApi.JobData data = api.new JobData();
+        data.id = "job_id_##";
+        expect(api.runPigQuery((File) anyObject(), anyString(), eq("-useHCatalog"))).andReturn(data);
+        replay(api);
+
+        Response response = doCreateJob("Test", "/tmp/script.pig", "-useHCatalog");
+        Assert.assertEquals(201, response.getStatus());
+
+        reset(api);
+        api.killJob(eq("job_id_##"));
+        replay(api);
+        JSONObject obj = (JSONObject)response.getEntity();
+        PigJob job = ((PigJob)obj.get("job"));
+        response = jobService.killJob(job.getId());
+        Assert.assertEquals(204, response.getStatus());
+    }
+
+    @Test
+    public void testJobStatusFlow() throws Exception {
+        HdfsApi hdfsApi = createNiceMock(HdfsApi.class);
+        expect(hdfsApi.copy(eq("/tmp/script.pig"), startsWith("/tmp/.pigjobs/"))).andReturn(true);
+
+        ByteArrayOutputStream do_stream = new ByteArrayOutputStream();
+
+        FSDataOutputStream stream = new FSDataOutputStream(do_stream);
+        expect(hdfsApi.create(anyString(), eq(true))).andReturn(stream);
+        replay(hdfsApi);
+        JobService.setHdfsApi(hdfsApi);
+
+        TempletonApi api = createNiceMock(TempletonApi.class);
+        jobService.getResourceManager().setTempletonApi(api);
+        TempletonApi.JobData data = api.new JobData();
+        data.id = "job_id_#";
+        expect(api.runPigQuery((File) anyObject(), anyString(), eq("-useHCatalog"))).andReturn(data);
+        replay(api);
+
+        Response response = doCreateJob("Test", "/tmp/script.pig", "-useHCatalog");
+
+        Assert.assertEquals("-useHCatalog", do_stream.toString());
+        Assert.assertEquals(201, response.getStatus());
+
+        PigJob job = ((PigJob) ((JSONObject)response.getEntity()).get("job"));
+        Assert.assertEquals(PigJob.Status.SUBMITTED, job.getStatus());
+        Assert.assertTrue(job.isInProgress());
+
+        // Retrieve status:
+        // SUBMITTED
+        reset(api);
+        TempletonApi.JobInfo info = api.new JobInfo();
+        expect(api.checkJob(eq("job_id_#"))).andReturn(info);
+        replay(api);
+        response = jobService.getJob(job.getId());
+        Assert.assertEquals(200, response.getStatus());
+        job = ((PigJob) ((JSONObject)response.getEntity()).get("job"));
+        Assert.assertEquals(PigJob.Status.SUBMITTED, job.getStatus());
+
+        // RUNNING
+        reset(api);
+        info = api.new JobInfo();
+        info.status = new HashMap<String, Object>();
+        info.status.put("runState", (double)PigJob.RUN_STATE_RUNNING);
+        info.percentComplete = "30% complete";
+        expect(api.checkJob(eq("job_id_#"))).andReturn(info);
+        replay(api);
+        response = jobService.getJob(job.getId());
+        Assert.assertEquals(200, response.getStatus());
+        job = ((PigJob) ((JSONObject)response.getEntity()).get("job"));
+        Assert.assertEquals(PigJob.Status.RUNNING, job.getStatus());
+        Assert.assertTrue(job.isInProgress());
+        Assert.assertEquals(30, (Object) job.getPercentComplete());
+
+        // SUCCEED
+        reset(api);
+        info = api.new JobInfo();
+        info.status = new HashMap<String, Object>();
+        info.status.put("runState", (double)PigJob.RUN_STATE_SUCCEEDED);
+        expect(api.checkJob(eq("job_id_#"))).andReturn(info);
+        replay(api);
+        response = jobService.getJob(job.getId());
+        Assert.assertEquals(200, response.getStatus());
+        job = ((PigJob) ((JSONObject)response.getEntity()).get("job"));
+        Assert.assertEquals(PigJob.Status.COMPLETED, job.getStatus());
+        Assert.assertFalse(job.isInProgress());
+        Assert.assertNull(job.getPercentComplete());
+
+        // PREP
+        reset(api);
+        info = api.new JobInfo();
+        info.status = new HashMap<String, Object>();
+        info.status.put("runState", (double)PigJob.RUN_STATE_PREP);
+        expect(api.checkJob(eq("job_id_#"))).andReturn(info);
+        replay(api);
+        response = jobService.getJob(job.getId());
+        Assert.assertEquals(200, response.getStatus());
+        job = ((PigJob) ((JSONObject)response.getEntity()).get("job"));
+        Assert.assertEquals(PigJob.Status.RUNNING, job.getStatus());
+
+        // FAILED
+        reset(api);
+        info = api.new JobInfo();
+        info.status = new HashMap<String, Object>();
+        info.status.put("runState", (double)PigJob.RUN_STATE_FAILED);
+        expect(api.checkJob(eq("job_id_#"))).andReturn(info);
+        replay(api);
+        response = jobService.getJob(job.getId());
+        Assert.assertEquals(200, response.getStatus());
+        job = ((PigJob) ((JSONObject)response.getEntity()).get("job"));
+        Assert.assertEquals(PigJob.Status.FAILED, job.getStatus());
+        Assert.assertFalse(job.isInProgress());
+
+        // KILLED
+        reset(api);
+        info = api.new JobInfo();
+        info.status = new HashMap<String, Object>();
+        info.status.put("runState", (double)PigJob.RUN_STATE_KILLED);
+        expect(api.checkJob(eq("job_id_#"))).andReturn(info);
+        replay(api);
+        response = jobService.getJob(job.getId());
+        Assert.assertEquals(200, response.getStatus());
+        job = ((PigJob) ((JSONObject)response.getEntity()).get("job"));
+        Assert.assertEquals(PigJob.Status.KILLED, job.getStatus());
+        Assert.assertFalse(job.isInProgress());
+    }
+}

http://git-wip-us.apache.org/repos/asf/ambari/blob/5eb22214/contrib/views/pig/src/test/java/org/apache/ambari/view/pig/test/ScriptTest.java
----------------------------------------------------------------------
diff --git a/contrib/views/pig/src/test/java/org/apache/ambari/view/pig/test/ScriptTest.java b/contrib/views/pig/src/test/java/org/apache/ambari/view/pig/test/ScriptTest.java
new file mode 100644
index 0000000..e7ddf3d
--- /dev/null
+++ b/contrib/views/pig/src/test/java/org/apache/ambari/view/pig/test/ScriptTest.java
@@ -0,0 +1,175 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.ambari.view.pig.test;
+
+import org.apache.ambari.view.pig.HDFSTest;
+import org.apache.ambari.view.pig.resources.files.FileService;
+import org.apache.ambari.view.pig.resources.scripts.ScriptService;
+import org.apache.ambari.view.pig.resources.scripts.models.PigScript;
+import org.json.simple.JSONObject;
+import org.junit.*;
+
+import javax.servlet.http.HttpServletResponse;
+import javax.ws.rs.core.Response;
+import javax.ws.rs.core.UriBuilder;
+import javax.ws.rs.core.UriInfo;
+import java.io.File;
+import java.net.URI;
+import java.util.List;
+import java.util.Map;
+
+import static org.easymock.EasyMock.*;
+
+public class ScriptTest extends HDFSTest {
+    private ScriptService scriptService;
+
+    @BeforeClass
+    public static void startUp() throws Exception {
+        HDFSTest.startUp(); // super
+    }
+
+    @AfterClass
+    public static void shutDown() throws Exception {
+        HDFSTest.shutDown(); // super
+        FileService.setHdfsApi(null); //cleanup API connection
+    }
+
+    @Override
+    @Before
+    public void setUp() throws Exception {
+        super.setUp();
+        scriptService = getService(ScriptService.class, handler, context);
+    }
+
+    @Override
+    protected void setupProperties(Map<String, String> properties, File baseDir) throws Exception {
+        super.setupProperties(properties, baseDir);
+        properties.put("dataworker.userScriptsPath", "/tmp/.pigscripts");
+    }
+
+    private Response doCreateScript() {
+        return doCreateScript("Luke", "/tmp/luke.pig", scriptService);
+    }
+
+    public static Response doCreateScript(String title, String path, ScriptService scriptService) {
+        ScriptService.PigScriptRequest request = new ScriptService.PigScriptRequest();
+        request.script = new PigScript();
+        request.script.setTitle(title);
+        request.script.setPigScript(path);
+
+        UriInfo uriInfo = createNiceMock(UriInfo.class);
+        URI uri = UriBuilder.fromUri("http://host/a/b").build();
+        expect(uriInfo.getAbsolutePath()).andReturn(uri);
+
+        HttpServletResponse resp_obj = createNiceMock(HttpServletResponse.class);
+
+        resp_obj.setHeader(eq("Location"), anyString());
+
+        replay(uriInfo, resp_obj);
+        return scriptService.saveScript(request, resp_obj, uriInfo);
+    }
+
+    private Response doCreateScript(String title, String path) {
+        return doCreateScript(title, path, scriptService);
+    }
+
+    @Test
+    public void createScript() {
+        Response response = doCreateScript();
+        Assert.assertEquals(201, response.getStatus());
+
+        JSONObject obj = (JSONObject)response.getEntity();
+        Assert.assertTrue(obj.containsKey("script"));
+        Assert.assertNotNull(((PigScript) obj.get("script")).getId());
+        Assert.assertFalse(((PigScript) obj.get("script")).getId().isEmpty());
+    }
+
+    @Test
+    public void createScriptAutoCreate() {
+        Response response = doCreateScript("Test", null);
+        Assert.assertEquals(201, response.getStatus());
+
+        JSONObject obj = (JSONObject)response.getEntity();
+        Assert.assertTrue(obj.containsKey("script"));
+        Assert.assertNotNull(((PigScript) obj.get("script")).getId());
+        Assert.assertFalse(((PigScript) obj.get("script")).getId().isEmpty());
+        Assert.assertFalse(((PigScript) obj.get("script")).getPigScript().isEmpty());
+    }
+
+    @Test
+    public void scriptNotFound() {
+        Response response2 = scriptService.getScript("4242");
+        Assert.assertEquals(404, response2.getStatus());
+    }
+
+    @Test
+    public void updateScript() {
+        Response createdScript = doCreateScript();
+        String createdScriptId = ((PigScript) ((JSONObject) createdScript.getEntity()).get("script")).getId();
+
+        ScriptService.PigScriptRequest request = new ScriptService.PigScriptRequest();
+        request.script = new PigScript();
+        request.script.setTitle("Updated Script");
+
+        Response response = scriptService.updateScript(request, createdScriptId);
+        Assert.assertEquals(204, response.getStatus());
+
+        Response response2 = scriptService.getScript(createdScriptId);
+        Assert.assertEquals(200, response2.getStatus());
+
+        JSONObject obj = ((JSONObject) response2.getEntity());
+        Assert.assertTrue(obj.containsKey("script"));
+        Assert.assertEquals(((PigScript) obj.get("script")).getTitle(), request.script.getTitle());
+    }
+
+    @Test
+    public void deleteScript() {
+        Response createdScript = doCreateScript();
+        String createdScriptId = ((PigScript) ((JSONObject) createdScript.getEntity()).get("script")).getId();
+
+        Response response = scriptService.deleteScript(createdScriptId);
+        Assert.assertEquals(204, response.getStatus());
+
+        Response response2 = scriptService.getScript(createdScriptId);
+        Assert.assertEquals(404, response2.getStatus());
+    }
+
+    @Test
+    public void listScripts() {
+        Response createdScript1 = doCreateScript("Title 1", "/path/to/file.pig");
+        Response createdScript2 = doCreateScript("Title 2", "/path/to/file.pig");
+        String createdScriptId = ((PigScript) ((JSONObject) createdScript1.getEntity()).get("script")).getId();
+
+        Response response = scriptService.getScriptList();
+        Assert.assertEquals(200, response.getStatus());
+
+        JSONObject obj = (JSONObject) response.getEntity();
+        Assert.assertTrue(obj.containsKey("scripts"));
+        List<PigScript> scripts = (List<PigScript>) obj.get("scripts");
+        boolean containsTitle = false;
+        for(PigScript script : scripts)
+            containsTitle = containsTitle || script.getTitle().compareTo("Title 1") == 0;
+        Assert.assertTrue(containsTitle);
+
+        containsTitle = false;
+        for(PigScript script : scripts)
+            containsTitle = containsTitle || script.getTitle().compareTo("Title 2") == 0;
+        Assert.assertTrue(containsTitle);
+    }
+}

http://git-wip-us.apache.org/repos/asf/ambari/blob/5eb22214/contrib/views/pig/src/test/java/org/apache/ambari/view/pig/test/ScriptTestHDFSUnmanaged.java
----------------------------------------------------------------------
diff --git a/contrib/views/pig/src/test/java/org/apache/ambari/view/pig/test/ScriptTestHDFSUnmanaged.java b/contrib/views/pig/src/test/java/org/apache/ambari/view/pig/test/ScriptTestHDFSUnmanaged.java
new file mode 100644
index 0000000..55a6d20
--- /dev/null
+++ b/contrib/views/pig/src/test/java/org/apache/ambari/view/pig/test/ScriptTestHDFSUnmanaged.java
@@ -0,0 +1,109 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.ambari.view.pig.test;
+
+
+import org.apache.ambari.view.ViewContext;
+import org.apache.ambari.view.ViewResourceHandler;
+import org.apache.ambari.view.pig.HDFSTest;
+import org.apache.ambari.view.pig.persistence.InstanceKeyValueStorage;
+import org.apache.ambari.view.pig.persistence.Storage;
+import org.apache.ambari.view.pig.resources.files.FileService;
+import org.apache.ambari.view.pig.resources.scripts.ScriptService;
+import org.apache.ambari.view.pig.persistence.utils.StorageUtil;
+import org.junit.*;
+
+import javax.ws.rs.core.Response;
+import javax.xml.ws.WebServiceException;
+import java.io.File;
+import java.io.IOException;
+import java.util.HashMap;
+import java.util.Map;
+
+import static org.easymock.EasyMock.*;
+
+public class ScriptTestHDFSUnmanaged extends HDFSTest {
+    private ScriptService scriptService;
+
+    @BeforeClass
+    public static void startUp() throws Exception {
+        HDFSTest.startUp(); // super
+    }
+
+    @AfterClass
+    public static void shutDown() throws Exception {
+        HDFSTest.shutDown(); // super
+        FileService.setHdfsApi(null); //cleanup API connection
+    }
+
+    @Override
+    @Before
+    public void setUp() throws Exception {
+        handler = createNiceMock(ViewResourceHandler.class);
+        context = createNiceMock(ViewContext.class);
+        FileService.setHdfsApi(null); //cleanup API connection
+        StorageUtil.setStorage(null);
+    }
+
+    @Test(expected=WebServiceException.class)
+    public void createScriptAutoCreateNoScriptsPath() throws IOException, InterruptedException {
+        Map<String, String> properties = new HashMap<String, String>();
+        baseDir = new File(DATA_DIRECTORY)
+                .getAbsoluteFile();
+        pigStorageFile = new File("./target/BasePigTest/storage.dat")
+                .getAbsoluteFile();
+
+        properties.put("dataworker.storagePath", pigStorageFile.toString());
+//        properties.put("dataworker.userScriptsPath", "/tmp/.pigscripts");
+        properties.put("dataworker.defaultFs", hdfsURI);
+
+        expect(context.getProperties()).andReturn(properties).anyTimes();
+        expect(context.getUsername()).andReturn("ambari-qa").anyTimes();
+
+        replay(handler, context);
+        scriptService = getService(ScriptService.class, handler, context);
+
+        doCreateScript("Test", null);
+    }
+
+    @Test
+    public void createScriptAutoCreateNoStoragePath() throws IOException, InterruptedException {
+        Map<String, String> properties = new HashMap<String, String>();
+        baseDir = new File(DATA_DIRECTORY)
+                .getAbsoluteFile();
+        pigStorageFile = new File("./target/BasePigTest/storage.dat")
+                .getAbsoluteFile();
+
+//        properties.put("dataworker.storagePath", pigStorageFile.toString());
+        properties.put("dataworker.userScriptsPath", "/tmp/.pigscripts");
+        properties.put("dataworker.defaultFs", hdfsURI);
+
+        expect(context.getProperties()).andReturn(properties).anyTimes();
+        expect(context.getUsername()).andReturn("ambari-qa").anyTimes();
+
+        replay(handler, context);
+
+        Storage storage = StorageUtil.getStorage(context);
+        Assert.assertEquals(InstanceKeyValueStorage.class.getSimpleName(), storage.getClass().getSimpleName());
+    }
+
+    private Response doCreateScript(String title, String path) {
+        return ScriptTest.doCreateScript(title, path, scriptService);
+    }
+}

http://git-wip-us.apache.org/repos/asf/ambari/blob/5eb22214/contrib/views/pig/src/test/java/org/apache/ambari/view/pig/test/ScriptTestUnmanaged.java
----------------------------------------------------------------------
diff --git a/contrib/views/pig/src/test/java/org/apache/ambari/view/pig/test/ScriptTestUnmanaged.java b/contrib/views/pig/src/test/java/org/apache/ambari/view/pig/test/ScriptTestUnmanaged.java
new file mode 100644
index 0000000..61d0004
--- /dev/null
+++ b/contrib/views/pig/src/test/java/org/apache/ambari/view/pig/test/ScriptTestUnmanaged.java
@@ -0,0 +1,92 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.ambari.view.pig.test;
+
+import org.apache.ambari.view.ViewContext;
+import org.apache.ambari.view.ViewResourceHandler;
+import org.apache.ambari.view.pig.BasePigTest;
+import org.apache.ambari.view.pig.HDFSTest;
+import org.apache.ambari.view.pig.resources.files.FileService;
+import org.apache.ambari.view.pig.resources.scripts.ScriptService;
+import org.apache.ambari.view.pig.resources.scripts.models.PigScript;
+import org.apache.hadoop.conf.Configuration;
+import org.apache.hadoop.fs.FileUtil;
+import org.apache.hadoop.hdfs.MiniDFSCluster;
+import org.json.simple.JSONObject;
+import org.junit.*;
+import org.junit.experimental.runners.Enclosed;
+import org.junit.runner.RunWith;
+
+import javax.servlet.http.HttpServletResponse;
+import javax.ws.rs.core.Response;
+import javax.ws.rs.core.UriBuilder;
+import javax.ws.rs.core.UriInfo;
+import javax.xml.ws.WebServiceException;
+import java.io.File;
+import java.io.IOException;
+import java.net.URI;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import static org.easymock.EasyMock.*;
+
+/**
+ * Tests without HDFS and predefined properties
+ */
+public class ScriptTestUnmanaged extends BasePigTest {
+    private ScriptService scriptService;
+    private File pigStorageFile;
+    private File baseDir;
+
+    @AfterClass
+    public static void shutDown() throws Exception {
+        FileService.setHdfsApi(null); //cleanup API connection
+    }
+
+    @Before
+    public void setUp() throws Exception {
+        handler = createNiceMock(ViewResourceHandler.class);
+        context = createNiceMock(ViewContext.class);
+
+        baseDir = new File(DATA_DIRECTORY)
+                .getAbsoluteFile();
+        pigStorageFile = new File("./target/BasePigTest/storage.dat")
+                .getAbsoluteFile();
+    }
+
+    private Response doCreateScript(String title, String path) {
+        return ScriptTest.doCreateScript(title, path, scriptService);
+    }
+
+    @Test(expected=WebServiceException.class)
+    public void createScriptAutoCreateNoDefaultFS() {
+        Map<String, String> properties = new HashMap<String, String>();
+        properties.put("dataworker.storagePath", pigStorageFile.toString());
+        properties.put("dataworker.userScriptsPath", "/tmp/.pigscripts");
+
+        expect(context.getProperties()).andReturn(properties).anyTimes();
+        expect(context.getUsername()).andReturn("ambari-qa").anyTimes();
+
+        replay(handler, context);
+        scriptService = getService(ScriptService.class, handler, context);
+
+        doCreateScript("Test", null);
+    }
+}

http://git-wip-us.apache.org/repos/asf/ambari/blob/5eb22214/contrib/views/pig/src/test/java/org/apache/ambari/view/pig/test/UDFTest.java
----------------------------------------------------------------------
diff --git a/contrib/views/pig/src/test/java/org/apache/ambari/view/pig/test/UDFTest.java b/contrib/views/pig/src/test/java/org/apache/ambari/view/pig/test/UDFTest.java
new file mode 100644
index 0000000..533499a
--- /dev/null
+++ b/contrib/views/pig/src/test/java/org/apache/ambari/view/pig/test/UDFTest.java
@@ -0,0 +1,116 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.ambari.view.pig.test;
+
+import org.apache.ambari.view.pig.BasePigTest;
+import org.apache.ambari.view.pig.resources.udf.UDFService;
+import org.apache.ambari.view.pig.resources.udf.models.UDF;
+import org.json.simple.JSONObject;
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Test;
+
+import javax.servlet.http.HttpServletResponse;
+import javax.ws.rs.core.Response;
+import javax.ws.rs.core.UriBuilder;
+import javax.ws.rs.core.UriInfo;
+import java.net.URI;
+
+import static org.easymock.EasyMock.*;
+import static org.easymock.EasyMock.replay;
+
+public class UDFTest extends BasePigTest {
+    private UDFService udfService;
+
+    @Override
+    @Before
+    public void setUp() throws Exception {
+        super.setUp();
+        udfService = getService(UDFService.class, handler, context);
+    }
+
+    private Response doCreateUDF() {
+        UDFService.UDFRequest request = new UDFService.UDFRequest();
+        request.udf = new UDF();
+        request.udf.setPath("/tmp/udf.jar");
+        request.udf.setName("TestUDF");
+
+        UriInfo uriInfo = createNiceMock(UriInfo.class);
+        URI uri = UriBuilder.fromUri("http://host/a/b").build();
+        expect(uriInfo.getAbsolutePath()).andReturn(uri);
+
+        HttpServletResponse resp_obj = createNiceMock(HttpServletResponse.class);
+
+        resp_obj.setHeader(eq("Location"), anyString());
+
+        replay(uriInfo, resp_obj);
+        return udfService.createUDF(request, resp_obj, uriInfo);
+    }
+
+    @Test
+    public void createUDF() {
+        Response response = doCreateUDF();
+        Assert.assertEquals(201, response.getStatus());
+
+        JSONObject obj = (JSONObject)response.getEntity();
+        Assert.assertTrue(obj.containsKey("udf"));
+        Assert.assertNotNull(((UDF) obj.get("udf")).getId());
+        Assert.assertFalse(((UDF) obj.get("udf")).getId().isEmpty());
+    }
+
+    @Test
+    public void udfNotFound() {
+        Response response2 = udfService.getUDF("4242");
+        Assert.assertEquals(404, response2.getStatus());
+    }
+
+    @Test
+    public void updateUDF() {
+        Response createdUDF = doCreateUDF();
+        String createdUdfId = ((UDF) ((JSONObject) createdUDF.getEntity()).get("udf")).getId();
+
+        UDFService.UDFRequest request = new UDFService.UDFRequest();
+        request.udf = new UDF();
+        request.udf.setPath("/tmp/updatedUDF.jar");
+        request.udf.setName("TestUDF2");
+
+        Response response = udfService.updateUDF(request, createdUdfId);
+        Assert.assertEquals(204, response.getStatus());
+
+        Response response2 = udfService.getUDF(createdUdfId);
+        Assert.assertEquals(200, response2.getStatus());
+
+        JSONObject obj = ((JSONObject) response2.getEntity());
+        Assert.assertTrue(obj.containsKey("udf"));
+        Assert.assertEquals(((UDF) obj.get("udf")).getName(), request.udf.getName());
+        Assert.assertEquals(((UDF) obj.get("udf")).getPath(), request.udf.getPath());
+    }
+
+    @Test
+    public void deleteUDF() {
+        Response createdUDF = doCreateUDF();
+        String createdUdfId = ((UDF) ((JSONObject) createdUDF.getEntity()).get("udf")).getId();
+
+        Response response = udfService.deleteUDF(createdUdfId);
+        Assert.assertEquals(204, response.getStatus());
+
+        Response response2 = udfService.getUDF(createdUdfId);
+        Assert.assertEquals(404, response2.getStatus());
+    }
+}

http://git-wip-us.apache.org/repos/asf/ambari/blob/5eb22214/contrib/views/pom.xml
----------------------------------------------------------------------
diff --git a/contrib/views/pom.xml b/contrib/views/pom.xml
new file mode 100644
index 0000000..e6fb0c7
--- /dev/null
+++ b/contrib/views/pom.xml
@@ -0,0 +1,133 @@
+<!--
+   Licensed to the Apache Software Foundation (ASF) under one or more
+   contributor license agreements.  See the NOTICE file distributed with
+   this work for additional information regarding copyright ownership.
+   The ASF licenses this file to You under the Apache License, Version 2.0
+   (the "License"); you may not use this file except in compliance with
+   the License.  You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.
+-->
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+  <modelVersion>4.0.0</modelVersion>
+  <groupId>org.apache.ambari.views</groupId>
+  <artifactId>ambari-views-poc</artifactId>
+  <packaging>pom</packaging>
+  <version>0.1.0-SNAPSHOT</version>
+  <name>Ambari Views Proof of Concept</name>
+  <modules>
+    <!--
+            <module>files</module>
+    -->
+    <module>pig</module>
+  </modules>
+  <build>
+    <pluginManagement>
+      <plugins>
+        <plugin>
+          <groupId>org.apache.rat</groupId>
+          <artifactId>apache-rat-plugin</artifactId>
+          <version>0.8</version>
+        </plugin>
+      </plugins>
+    </pluginManagement>
+    <plugins>
+      <plugin>
+        <groupId>org.apache.rat</groupId>
+        <artifactId>apache-rat-plugin</artifactId>
+        <configuration>
+          <excludes>
+            <!--GIT files-->
+            <exclude>.git/</exclude>
+            <exclude>**/.gitignore</exclude>
+            <exclude>**/.gitattributes</exclude>
+            <!--gitignore content-->
+            <exclude>.idea/</exclude>
+            <exclude>pass.txt</exclude>
+            <exclude>.DS_Store</exclude>
+            <exclude>.iml/</exclude>
+            <exclude>.classpath</exclude>
+            <exclude>.project</exclude>
+            <exclude>.settings</exclude>
+
+            <exclude>**/*.json</exclude>
+            <exclude>**/*.svg</exclude>
+            <exclude>**/vendor/*</exclude>
+            <exclude>**/bin</exclude>
+          </excludes>
+        </configuration>
+      </plugin>
+      <plugin>
+        <artifactId>maven-assembly-plugin</artifactId>
+        <executions>
+          <execution>
+            <phase>package</phase>
+            <goals>
+              <goal>attached</goal>
+            </goals>
+          </execution>
+        </executions>
+        <configuration>
+          <descriptorRefs>
+            <descriptorRef>jar-with-dependencies</descriptorRef>
+          </descriptorRefs>
+          <outputDirectory>${basedir}/target</outputDirectory>
+        </configuration>
+      </plugin>
+      <plugin>
+        <groupId>org.apache.maven.plugins</groupId>
+        <artifactId>maven-compiler-plugin</artifactId>
+        <version>3.1</version>
+        <configuration>
+          <source>1.6</source>
+          <target>1.6</target>
+        </configuration>
+      </plugin>
+    </plugins>
+
+  </build>
+  <dependencyManagement>
+    <dependencies>
+      <dependency>
+        <groupId>org.glassfish.jersey.containers</groupId>
+        <artifactId>jersey-container-servlet</artifactId>
+        <version>2.6</version>
+      </dependency>
+      <dependency>
+        <groupId>junit</groupId>
+        <artifactId>junit</artifactId>
+        <version>4.11</version>
+        <scope>test</scope>
+      </dependency>
+      <dependency>
+        <groupId>com.google.inject</groupId>
+        <artifactId>guice</artifactId>
+        <version>4.0-beta</version>
+      </dependency>
+      <dependency>
+        <groupId>org.easymock</groupId>
+        <artifactId>easymock</artifactId>
+        <version>3.2</version>
+        <scope>test</scope>
+      </dependency>
+      <dependency>
+        <groupId>com.googlecode.json-simple</groupId>
+        <artifactId>json-simple</artifactId>
+        <version>1.1.1</version>
+      </dependency>
+      <dependency>
+        <groupId>org.apache.ambari</groupId>
+        <artifactId>ambari-views</artifactId>
+        <version>[1.5.0.1,)</version>
+      </dependency>
+    </dependencies>
+  </dependencyManagement>
+
+</project>


[6/7] AMBARI-5616 - Ambari Views: Pig view (Roman Rader via tbeerbower)

Posted by tb...@apache.org.
http://git-wip-us.apache.org/repos/asf/ambari/blob/5eb22214/contrib/views/pig/src/main/java/org/apache/ambari/view/pig/resources/jobs/JobService.java
----------------------------------------------------------------------
diff --git a/contrib/views/pig/src/main/java/org/apache/ambari/view/pig/resources/jobs/JobService.java b/contrib/views/pig/src/main/java/org/apache/ambari/view/pig/resources/jobs/JobService.java
new file mode 100644
index 0000000..23705e9
--- /dev/null
+++ b/contrib/views/pig/src/main/java/org/apache/ambari/view/pig/resources/jobs/JobService.java
@@ -0,0 +1,243 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.ambari.view.pig.resources.jobs;
+
+import com.google.inject.Inject;
+import org.apache.ambari.view.ViewResourceHandler;
+import org.apache.ambari.view.pig.persistence.utils.ItemNotFound;
+import org.apache.ambari.view.pig.persistence.utils.OnlyOwnersFilteringStrategy;
+import org.apache.ambari.view.pig.resources.files.FileResource;
+import org.apache.ambari.view.pig.resources.jobs.models.PigJob;
+import org.apache.ambari.view.pig.services.BaseService;
+import org.apache.ambari.view.pig.utils.FilePaginator;
+import org.json.simple.JSONObject;
+
+import javax.servlet.http.HttpServletResponse;
+import javax.ws.rs.*;
+import javax.ws.rs.core.*;
+import javax.xml.ws.WebServiceException;
+import java.io.IOException;
+import java.util.List;
+import java.util.concurrent.Callable;
+
+/**
+ * Servlet for Pig Jobs
+ * API:
+ * GET /:id
+ *      read job info
+ * POST /
+ *      create new job
+ *      Required: scriptId
+ *      Optional: params
+ * GET /
+ *      get all jobs of current user
+ * GET /:id/notify
+ *      callback from Templeton
+ */
+public class JobService extends BaseService {
+    @Inject
+    ViewResourceHandler handler;
+
+    protected JobResourceManager resourceManager = null;
+
+    public synchronized JobResourceManager getResourceManager() {
+        if (resourceManager == null) {
+            resourceManager = new JobResourceManager(context);
+        }
+        return resourceManager;
+    }
+
+    public synchronized void setResourceManager(JobResourceManager resourceManager) {
+        this.resourceManager = resourceManager;
+    }
+
+    /**
+     * Get single item
+     */
+    @GET
+    @Path("{jobId}")
+    @Produces(MediaType.APPLICATION_JSON)
+    public Response getJob(@PathParam("jobId") String jobId) {
+        PigJob job = null;
+        try {
+            job = getResourceManager().read(jobId);
+        } catch (ItemNotFound itemNotFound) {
+            return Response.status(404).build();
+        }
+        getResourceManager().retrieveJobStatus(job);
+        JSONObject object = new JSONObject();
+        object.put("job", job);
+        return Response.ok(object).build();
+    }
+
+    /**
+     * Get single item
+     */
+    @DELETE
+    @Path("{jobId}")
+    public Response killJob(@PathParam("jobId") String jobId) throws IOException {
+        PigJob job = null;
+        try {
+            job = getResourceManager().read(jobId);
+        } catch (ItemNotFound itemNotFound) {
+            return Response.status(404).build();
+        }
+        getResourceManager().killJob(job);
+        return Response.status(204).build();
+    }
+
+    /**
+     * Callback from templeton
+     */
+    @GET
+    @Path("{jobId}/notify")
+    public Response jobCompletionNotification(@Context HttpHeaders headers,
+                                              @Context UriInfo ui,
+                                              @PathParam("jobId") final String jobId) {
+        PigJob job = null;
+        try {
+            job = getResourceManager().ignorePermissions(new Callable<PigJob>() {
+                public PigJob call() throws Exception {
+                    PigJob job = null;
+                    try {
+                        job = getResourceManager().read(jobId);
+                    } catch (ItemNotFound itemNotFound) {
+                        return null;
+                    }
+                    return job;
+                }
+            });
+        } catch (Exception e) {
+            return Response.status(500).build();
+        }
+        if (job == null)
+            return Response.status(404).build();
+
+        getResourceManager().retrieveJobStatus(job);
+        return Response.ok().build();
+    }
+
+    @GET
+    @Path("{jobId}/results/{fileName}")
+    @Produces(MediaType.APPLICATION_JSON)
+    public Response jobExitCode(@Context HttpHeaders headers,
+                                @Context UriInfo ui,
+                                @PathParam("jobId") String jobId,
+                                @PathParam("fileName") String fileName,
+                                @QueryParam("page") Long page) {
+        PigJob job = null;
+        try {
+            job = getResourceManager().read(jobId);
+        } catch (ItemNotFound itemNotFound) {
+            return Response.ok("No such job").status(404).build();
+        }
+        try {
+            String filePath = job.getStatusDir() + "/" + fileName;
+            LOG.debug("Reading file " + filePath);
+            FilePaginator paginator = new FilePaginator(filePath, context);
+
+            if (page == null)
+                page = 0L;
+
+            FileResource file = new FileResource();
+            file.filePath = filePath;
+            file.fileContent = paginator.readPage(page);
+            file.hasNext = paginator.pageCount() > page + 1;
+            file.page = page;
+            file.pageCount = paginator.pageCount();
+
+            JSONObject object = new JSONObject();
+            object.put("file", file);
+            return Response.ok(object).status(200).build();
+        } catch (IOException e) {
+            return Response.ok(e.getMessage()).status(404).build();
+        } catch (InterruptedException e) {
+            return Response.ok(e.getMessage()).status(404).build();
+        }
+    }
+
+    /**
+     * Get all jobs
+     */
+    @GET
+    @Produces(MediaType.APPLICATION_JSON)
+    public Response getJobList(@Context HttpHeaders headers, @Context UriInfo ui) {
+        List allJobs = getResourceManager().readAll(
+                new OnlyOwnersFilteringStrategy(this.context.getUsername()));
+
+        JSONObject object = new JSONObject();
+        object.put("jobs", allJobs);
+        return Response.ok(object).build();
+    }
+
+    /**
+     * Create job
+     */
+    @POST
+    @Consumes(MediaType.APPLICATION_JSON)
+    @Produces(MediaType.APPLICATION_JSON)
+    public Response runJob(PigJobRequest request, @Context HttpServletResponse response,
+                               @Context UriInfo ui) {
+        if (!request.validatePOST()) {
+            return badRequestResponse(request.explainPOST());
+        }
+        try {
+            getResourceManager().create(request.job);
+        } catch (IllegalArgumentException e) {
+            return badRequestResponse(e.getMessage());
+        } catch (WebServiceException e) {
+            return serverErrorResponse(e.getMessage());
+        }
+
+        PigJob job = null;
+
+        try {
+            job = getResourceManager().read(request.job.getId());
+        } catch (ItemNotFound itemNotFound) {
+            return Response.status(404).build();
+        }
+
+        response.setHeader("Location",
+                String.format("%s/%s", ui.getAbsolutePath().toString(), request.job.getId()));
+
+        JSONObject object = new JSONObject();
+        object.put("job", job);
+        return Response.ok(object).status(201).build();
+    }
+
+    public static class PigJobRequest {
+        public PigJob job;
+
+        public String explainPOST() {
+            StringBuilder result = new StringBuilder();
+            if ((job.getPigScript() == null || job.getPigScript().isEmpty()) &&
+                    (job.getForcedContent() == null || job.getForcedContent().isEmpty()))
+                result.append("No pigScript file or forcedContent specifed;");
+            if (job.getTitle() == null || job.getTitle().isEmpty())
+                result.append("No title specifed;");
+            if (job.getId() != null && !job.getTitle().isEmpty())
+                result.append("ID should not exists in creation request;");
+            return result.toString();
+        }
+
+        public boolean validatePOST() {
+            return explainPOST().isEmpty();
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/ambari/blob/5eb22214/contrib/views/pig/src/main/java/org/apache/ambari/view/pig/resources/jobs/models/PigJob.java
----------------------------------------------------------------------
diff --git a/contrib/views/pig/src/main/java/org/apache/ambari/view/pig/resources/jobs/models/PigJob.java b/contrib/views/pig/src/main/java/org/apache/ambari/view/pig/resources/jobs/models/PigJob.java
new file mode 100644
index 0000000..e49c267
--- /dev/null
+++ b/contrib/views/pig/src/main/java/org/apache/ambari/view/pig/resources/jobs/models/PigJob.java
@@ -0,0 +1,253 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.ambari.view.pig.resources.jobs.models;
+
+import org.apache.ambari.view.pig.persistence.utils.PersonalResource;
+import org.apache.commons.beanutils.BeanUtils;
+import org.codehaus.jackson.annotate.JsonIgnore;
+
+import java.io.Serializable;
+import java.lang.reflect.InvocationTargetException;
+import java.util.Map;
+
+/**
+ * Bean to represent Pig job
+ *
+ * Job lifecycle:
+ * SUBMITTING
+ *     |
+ *   [POST to Templeton]
+ *     |            |
+ * SUBMITTED   SUBMIT_FAILED
+ *     |
+ *     |
+  *   [GET result from job/:job_id]
+ *     |            |             |
+ * COMPLETED      KILLED        FAILED
+ */
+public class PigJob implements Serializable, PersonalResource {
+
+    public enum Status {
+        UNKNOWN,
+        SUBMITTING, SUBMITTED, RUNNING,  // in progress
+        SUBMIT_FAILED, COMPLETED, FAILED, KILLED  // finished
+    }
+
+    public boolean isInProgress() {
+        return status == Status.SUBMITTED || status == Status.SUBMITTING ||
+                status == Status.RUNNING;
+    }
+
+    public static final int RUN_STATE_RUNNING = 1;
+    public static final int RUN_STATE_SUCCEEDED = 2;
+    public static final int RUN_STATE_FAILED = 3;
+    public static final int RUN_STATE_PREP = 4;
+    public static final int RUN_STATE_KILLED = 5;
+
+    public PigJob() {
+    }
+
+    public PigJob(Map<String, Object> stringObjectMap) throws InvocationTargetException, IllegalAccessException {
+        BeanUtils.populate(this, stringObjectMap);
+    }
+
+    String id = null;
+    String scriptId = null;
+
+    // cloned script data
+    String pigScript = null;
+    String pythonScript = null;
+    String title = null;
+    String templetonArguments = null;
+    String owner;
+
+    // job info
+    String forcedContent = null;
+
+    /**
+     * jobType possible values:
+     * null - regular execute
+     * "explain"
+     * "syntax_check"
+     */
+    String jobType = null;
+
+    /**
+     * Additional file to use in Explain job
+     */
+    String sourceFile = null;
+    String sourceFileContent = null;
+
+    String statusDir;
+    Long dateStarted = 0L;
+    String jobId = null;
+
+    // status fields (not reliable)
+    Status status = Status.UNKNOWN;
+    Integer percentComplete = null;
+
+    @Override
+    public boolean equals(Object o) {
+        if (this == o) return true;
+        if (!(o instanceof PigJob)) return false;
+
+        PigJob pigScript = (PigJob) o;
+
+        if (!id.equals(pigScript.id)) return false;
+
+        return true;
+    }
+
+    @Override
+    public int hashCode() {
+        return id.hashCode();
+    }
+
+    @Override
+    public String getId() {
+        return id;
+    }
+
+    @Override
+    public void setId(String id) {
+        this.id = id;
+    }
+
+    @Override
+    public String getOwner() {
+        return owner;
+    }
+
+    @Override
+    public void setOwner(String owner) {
+        this.owner = owner;
+    }
+
+    public Status getStatus() {
+        return status;
+    }
+
+    public void setStatus(Status status) {
+        this.status = status;
+    }
+
+    public String getScriptId() {
+        return scriptId;
+    }
+
+    public void setScriptId(String scriptId) {
+        this.scriptId = scriptId;
+    }
+
+    public String getTempletonArguments() {
+        return templetonArguments;
+    }
+
+    public void setTempletonArguments(String templetonArguments) {
+        this.templetonArguments = templetonArguments;
+    }
+
+    public String getPigScript() {
+        return pigScript;
+    }
+
+    public void setPigScript(String pigScript) {
+        this.pigScript = pigScript;
+    }
+
+    public String getJobId() {
+        return jobId;
+    }
+
+    public void setJobId(String jobId) {
+        this.jobId = jobId;
+    }
+
+    public String getTitle() {
+        return title;
+    }
+
+    public void setTitle(String title) {
+        this.title = title;
+    }
+
+    public void setStatusDir(String statusDir) {
+        this.statusDir = statusDir;
+    }
+
+    public String getStatusDir() {
+        return statusDir;
+    }
+
+    public Long getDateStarted() {
+        return dateStarted;
+    }
+
+    public void setDateStarted(Long dateStarted) {
+        this.dateStarted = dateStarted;
+    }
+
+    public Integer getPercentComplete() {
+        return percentComplete;
+    }
+
+    public void setPercentComplete(Integer percentComplete) {
+        this.percentComplete = percentComplete;
+    }
+
+    public String getPythonScript() {
+        return pythonScript;
+    }
+
+    public void setPythonScript(String pythonScript) {
+        this.pythonScript = pythonScript;
+    }
+
+    public String getForcedContent() {
+        return forcedContent;
+    }
+
+    public void setForcedContent(String forcedContent) {
+        this.forcedContent = forcedContent;
+    }
+
+    public String getJobType() {
+        return jobType;
+    }
+
+    public void setJobType(String jobType) {
+        this.jobType = jobType;
+    }
+
+    public String getSourceFileContent() {
+        return sourceFileContent;
+    }
+
+    public void setSourceFileContent(String sourceFileContent) {
+        this.sourceFileContent = sourceFileContent;
+    }
+
+    public String getSourceFile() {
+        return sourceFile;
+    }
+
+    public void setSourceFile(String sourceFile) {
+        this.sourceFile = sourceFile;
+    }
+}

http://git-wip-us.apache.org/repos/asf/ambari/blob/5eb22214/contrib/views/pig/src/main/java/org/apache/ambari/view/pig/resources/jobs/utils/JobPolling.java
----------------------------------------------------------------------
diff --git a/contrib/views/pig/src/main/java/org/apache/ambari/view/pig/resources/jobs/utils/JobPolling.java b/contrib/views/pig/src/main/java/org/apache/ambari/view/pig/resources/jobs/utils/JobPolling.java
new file mode 100644
index 0000000..31eabae
--- /dev/null
+++ b/contrib/views/pig/src/main/java/org/apache/ambari/view/pig/resources/jobs/utils/JobPolling.java
@@ -0,0 +1,143 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.ambari.view.pig.resources.jobs.utils;
+
+import org.apache.ambari.view.ViewContext;
+import org.apache.ambari.view.pig.persistence.utils.ItemNotFound;
+import org.apache.ambari.view.pig.resources.jobs.JobResourceManager;
+import org.apache.ambari.view.pig.resources.jobs.models.PigJob;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Observable;
+import java.util.concurrent.Executors;
+import java.util.concurrent.ScheduledExecutorService;
+import java.util.concurrent.ScheduledFuture;
+import java.util.concurrent.TimeUnit;
+
+/**
+ * Polling manager
+ * Makes scheduled repeated polling of templeton to
+ * be aware of happen events like job finished,
+ * killed, changed progress and so on.
+ */
+public class JobPolling implements Runnable {
+    private final static Logger LOG =
+            LoggerFactory.getLogger(JobPolling.class);
+
+    /**
+     * We should limit count of concurrent calls to templeton
+     * to avoid high load on component
+     */
+    private static final int WORKER_COUNT = 2;
+
+    private static final int POLLING_DELAY = 10*60;  // 10 minutes
+
+    /**
+     * In LONG_JOB_THRESHOLD seconds job reschedules polling from POLLING_DELAY to LONG_POLLING_DELAY
+     */
+    private static final int LONG_POLLING_DELAY = 60*60; // 1 hour
+    private static final int LONG_JOB_THRESHOLD = 60*60; // 1 hour
+
+    private static final ScheduledExecutorService pollWorkersPool = Executors.newScheduledThreadPool(WORKER_COUNT);
+
+    private static final Map<String, JobPolling> jobPollers = new HashMap<String, JobPolling>();
+
+    private JobResourceManager resourceManager = null;
+    private final ViewContext context;
+    private PigJob job;
+    private volatile ScheduledFuture<?> thisFuture;
+
+    private JobPolling(ViewContext context, PigJob job) {
+        this.context = context;
+        this.job = job;
+    }
+
+    protected synchronized JobResourceManager getResourceManager() {
+        if (resourceManager == null) {
+            resourceManager = new JobResourceManager(context);
+        }
+        return resourceManager;
+    }
+
+    public void run() {
+        LOG.debug("Polling job status " + job.getJobId() + " #" + job.getId());
+        try {
+            job = getResourceManager().read(job.getId());
+        } catch (ItemNotFound itemNotFound) {
+            LOG.error("Job " + job.getJobId() + " does not exist! Polling canceled");
+            thisFuture.cancel(false);
+            return;
+        }
+        getResourceManager().retrieveJobStatus(job);
+
+        Long time = System.currentTimeMillis() / 1000L;
+        if (time - job.getDateStarted() > LONG_JOB_THRESHOLD) {
+            LOG.debug("Job becomes long.. Rescheduling polling to longer period");
+            // If job running longer than LONG_JOB_THRESHOLD, reschedule
+            // it to poll every LONG_POLLING_DELAY instead of POLLING_DELAY
+            thisFuture.cancel(false);
+            scheduleJobPolling(true);
+        }
+
+        switch (job.getStatus()) {
+            case SUBMIT_FAILED:
+            case COMPLETED:
+            case FAILED:
+            case KILLED:
+                LOG.debug("Job finished. Polling canceled");
+                thisFuture.cancel(false);
+                break;
+            default:
+        }
+    }
+
+    private void scheduleJobPolling(boolean longDelay) {
+        if (!longDelay) {
+            thisFuture = pollWorkersPool.scheduleWithFixedDelay(this,
+                    POLLING_DELAY, POLLING_DELAY, TimeUnit.SECONDS);
+        } else {
+            thisFuture = pollWorkersPool.scheduleWithFixedDelay(this,
+                    LONG_POLLING_DELAY, LONG_POLLING_DELAY, TimeUnit.SECONDS);
+        }
+    }
+
+    private void scheduleJobPolling() {
+        scheduleJobPolling(false);
+    }
+
+    /**
+     * Schedule job polling
+     * @param context ViewContext of web app
+     * @param job job instance
+     * @return returns false if already scheduled
+     */
+    public static boolean pollJob(ViewContext context, PigJob job) {
+        if (jobPollers.get(job.getJobId()) == null) {
+            LOG.debug("Setting up polling for " + job.getJobId());
+            JobPolling polling = new JobPolling(context, job);
+            polling.scheduleJobPolling();
+            jobPollers.put(job.getJobId(), polling);
+            return true;
+        }
+        return false;
+    }
+}

http://git-wip-us.apache.org/repos/asf/ambari/blob/5eb22214/contrib/views/pig/src/main/java/org/apache/ambari/view/pig/resources/scripts/ScriptResourceManager.java
----------------------------------------------------------------------
diff --git a/contrib/views/pig/src/main/java/org/apache/ambari/view/pig/resources/scripts/ScriptResourceManager.java b/contrib/views/pig/src/main/java/org/apache/ambari/view/pig/resources/scripts/ScriptResourceManager.java
new file mode 100644
index 0000000..9714d27
--- /dev/null
+++ b/contrib/views/pig/src/main/java/org/apache/ambari/view/pig/resources/scripts/ScriptResourceManager.java
@@ -0,0 +1,101 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.ambari.view.pig.resources.scripts;
+
+import org.apache.ambari.view.ViewContext;
+import org.apache.ambari.view.pig.persistence.utils.ItemNotFound;
+import org.apache.ambari.view.pig.resources.PersonalCRUDResourceManager;
+import org.apache.ambari.view.pig.resources.scripts.models.PigScript;
+import org.apache.ambari.view.pig.services.BaseService;
+import org.apache.hadoop.fs.FSDataOutputStream;
+import org.apache.hadoop.fs.FileAlreadyExistsException;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import javax.xml.ws.WebServiceException;
+import java.io.IOException;
+import java.text.SimpleDateFormat;
+import java.util.Date;
+
+public class ScriptResourceManager extends PersonalCRUDResourceManager<PigScript> {
+    private final static Logger LOG =
+            LoggerFactory.getLogger(ScriptResourceManager.class);
+
+    public ScriptResourceManager(ViewContext context) {
+        super(PigScript.class, context);
+    }
+
+    @Override
+    public PigScript create(PigScript object) {
+        super.create(object);
+        if (object.getPigScript() == null || object.getPigScript().isEmpty()) {
+            createDefaultScriptFile(object);
+        }
+        return object;
+    }
+
+    private void createDefaultScriptFile(PigScript object) {
+        String userScriptsPath = context.getProperties().get("dataworker.userScriptsPath");
+        if (userScriptsPath == null) {
+            String msg = "dataworker.userScriptsPath is not configured!";
+            LOG.error(msg);
+            throw new WebServiceException(msg);
+        }
+        int checkId = 0;
+
+        boolean fileCreated;
+        String newFilePath;
+        do {
+            String normalizedName = object.getTitle().replaceAll("[^a-zA-Z0-9 ]+", "").replaceAll(" ", "_").toLowerCase();
+            String timestamp = new SimpleDateFormat("yyyy-MM-dd_hh-mm").format(new Date());
+            newFilePath = String.format(userScriptsPath +
+                    "/%s/%s-%s%s.pig", context.getUsername(),
+                    normalizedName, timestamp, (checkId == 0)?"":"_"+checkId);
+            LOG.debug("Trying to create new file " + newFilePath);
+
+            try {
+                FSDataOutputStream stream = BaseService.getHdfsApi(context).create(newFilePath, false);
+                stream.close();
+                fileCreated = true;
+                LOG.debug("File created successfully!");
+            } catch (FileAlreadyExistsException e) {
+                fileCreated = false;
+                LOG.debug("File already exists. Trying next id");
+            } catch (IOException e) {
+                try {
+                    delete(object.getId());
+                } catch (ItemNotFound itemNotFound) {
+                    throw new WebServiceException("Error in creation, during clean up: " + itemNotFound.toString(), itemNotFound);
+                }
+                throw new WebServiceException("Error in creation: " + e.toString(), e);
+            } catch (InterruptedException e) {
+                try {
+                    delete(object.getId());
+                } catch (ItemNotFound itemNotFound) {
+                    throw new WebServiceException("Error in creation, during clean up: " + itemNotFound.toString(), itemNotFound);
+                }
+                throw new WebServiceException("Error in creation: " + e.toString(), e);
+            }
+            checkId += 1;
+        } while (!fileCreated);
+
+        object.setPigScript(newFilePath);
+        getPigStorage().store(object);
+    }
+}

http://git-wip-us.apache.org/repos/asf/ambari/blob/5eb22214/contrib/views/pig/src/main/java/org/apache/ambari/view/pig/resources/scripts/ScriptResourceProvider.java
----------------------------------------------------------------------
diff --git a/contrib/views/pig/src/main/java/org/apache/ambari/view/pig/resources/scripts/ScriptResourceProvider.java b/contrib/views/pig/src/main/java/org/apache/ambari/view/pig/resources/scripts/ScriptResourceProvider.java
new file mode 100644
index 0000000..478a460
--- /dev/null
+++ b/contrib/views/pig/src/main/java/org/apache/ambari/view/pig/resources/scripts/ScriptResourceProvider.java
@@ -0,0 +1,103 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.ambari.view.pig.resources.scripts;
+
+import com.google.inject.Inject;
+import org.apache.ambari.view.*;
+import org.apache.ambari.view.pig.persistence.utils.ItemNotFound;
+import org.apache.ambari.view.pig.persistence.utils.OnlyOwnersFilteringStrategy;
+import org.apache.ambari.view.pig.resources.PersonalCRUDResourceManager;
+import org.apache.ambari.view.pig.resources.scripts.models.PigScript;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.lang.reflect.InvocationTargetException;
+import java.util.*;
+
+public class ScriptResourceProvider implements ResourceProvider<PigScript> {
+    @Inject
+    ViewContext context;
+
+    protected ScriptResourceManager resourceManager = null;
+    protected final static Logger LOG =
+            LoggerFactory.getLogger(ScriptResourceProvider.class);
+
+    protected synchronized PersonalCRUDResourceManager<PigScript> getResourceManager() {
+        if (resourceManager == null) {
+            resourceManager = new ScriptResourceManager(context);
+        }
+        return resourceManager;
+    }
+
+    @Override
+    public PigScript getResource(String resourceId, Set<String> properties) throws SystemException, NoSuchResourceException, UnsupportedPropertyException {
+        try {
+            return getResourceManager().read(resourceId);
+        } catch (ItemNotFound itemNotFound) {
+            throw new NoSuchResourceException(resourceId);
+        }
+    }
+
+    @Override
+    public Set<PigScript> getResources(ReadRequest readRequest) throws SystemException, NoSuchResourceException, UnsupportedPropertyException {
+        return new HashSet<PigScript>(getResourceManager().readAll(
+                new OnlyOwnersFilteringStrategy(this.context.getUsername())));
+    }
+
+    @Override
+    public void createResource(String s, Map<String, Object> stringObjectMap) throws SystemException, ResourceAlreadyExistsException, NoSuchResourceException, UnsupportedPropertyException {
+        PigScript script = null;
+        try {
+            script = new PigScript(stringObjectMap);
+        } catch (InvocationTargetException e) {
+            throw new SystemException("error on creating resource", e);
+        } catch (IllegalAccessException e) {
+            throw new SystemException("error on creating resource", e);
+        }
+        getResourceManager().create(script);
+    }
+
+    @Override
+    public boolean updateResource(String resourceId, Map<String, Object> stringObjectMap) throws SystemException, NoSuchResourceException, UnsupportedPropertyException {
+        PigScript script = null;
+        try {
+            script = new PigScript(stringObjectMap);
+        } catch (InvocationTargetException e) {
+            throw new SystemException("error on updating resource", e);
+        } catch (IllegalAccessException e) {
+            throw new SystemException("error on updating resource", e);
+        }
+        try {
+            getResourceManager().update(script, resourceId);
+        } catch (ItemNotFound itemNotFound) {
+            throw new NoSuchResourceException(resourceId);
+        }
+        return true;
+    }
+
+    @Override
+    public boolean deleteResource(String resourceId) throws SystemException, NoSuchResourceException, UnsupportedPropertyException {
+        try {
+            getResourceManager().delete(resourceId);
+        } catch (ItemNotFound itemNotFound) {
+            throw new NoSuchResourceException(resourceId);
+        }
+        return true;
+    }
+}

http://git-wip-us.apache.org/repos/asf/ambari/blob/5eb22214/contrib/views/pig/src/main/java/org/apache/ambari/view/pig/resources/scripts/ScriptService.java
----------------------------------------------------------------------
diff --git a/contrib/views/pig/src/main/java/org/apache/ambari/view/pig/resources/scripts/ScriptService.java b/contrib/views/pig/src/main/java/org/apache/ambari/view/pig/resources/scripts/ScriptService.java
new file mode 100644
index 0000000..c07f985
--- /dev/null
+++ b/contrib/views/pig/src/main/java/org/apache/ambari/view/pig/resources/scripts/ScriptService.java
@@ -0,0 +1,154 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.ambari.view.pig.resources.scripts;
+
+import com.google.inject.Inject;
+import org.apache.ambari.view.ViewResourceHandler;
+import org.apache.ambari.view.pig.persistence.utils.OnlyOwnersFilteringStrategy;
+import org.apache.ambari.view.pig.persistence.utils.ItemNotFound;
+import org.apache.ambari.view.pig.resources.PersonalCRUDResourceManager;
+import org.apache.ambari.view.pig.resources.scripts.models.PigScript;
+import org.apache.ambari.view.pig.services.BaseService;
+import org.json.simple.JSONObject;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import javax.servlet.http.HttpServletResponse;
+import javax.ws.rs.*;
+import javax.ws.rs.core.*;
+import java.util.List;
+
+/**
+ * Servlet for scripts
+ * API:
+ * GET /:id
+ *      read script
+ * POST /
+ *      create new script
+ *      Required: title, pigScript
+ * GET /
+ *      get all scripts of current user
+ */
+public class ScriptService extends BaseService {
+    @Inject
+    ViewResourceHandler handler;
+
+    protected ScriptResourceManager resourceManager = null;
+    protected final static Logger LOG =
+            LoggerFactory.getLogger(ScriptService.class);
+
+    protected synchronized PersonalCRUDResourceManager<PigScript> getResourceManager() {
+        if (resourceManager == null) {
+            resourceManager = new ScriptResourceManager(context);
+        }
+        return resourceManager;
+    }
+
+    /**
+     * Get single item
+     */
+    @GET
+    @Path("{scriptId}")
+    @Produces(MediaType.APPLICATION_JSON)
+    public Response getScript(@PathParam("scriptId") String scriptId) {
+        PigScript script = null;
+        try {
+            script = getResourceManager().read(scriptId);
+        } catch (ItemNotFound itemNotFound) {
+            return Response.status(404).build();
+        }
+        JSONObject object = new JSONObject();
+        object.put("script", script);
+        return Response.ok(object).build();
+    }
+
+    /**
+     * Delete single item
+     */
+    @DELETE
+    @Path("{scriptId}")
+    public Response deleteScript(@PathParam("scriptId") String scriptId) {
+        try {
+            getResourceManager().delete(scriptId);
+        } catch (ItemNotFound itemNotFound) {
+            return Response.status(404).build();
+        }
+        return Response.status(204).build();
+    }
+
+    /**
+     * Get all scripts
+     */
+    @GET
+    @Produces(MediaType.APPLICATION_JSON)
+    public Response getScriptList() {
+        LOG.debug("Getting all scripts");
+        List allScripts = getResourceManager().readAll(
+                new OnlyOwnersFilteringStrategy(this.context.getUsername()));
+
+        JSONObject object = new JSONObject();
+        object.put("scripts", allScripts);
+        return Response.ok(object).build();
+    }
+
+    /**
+     * Update item
+     */
+    @PUT
+    @Path("{scriptId}")
+    @Consumes(MediaType.APPLICATION_JSON)
+    public Response updateScript(PigScriptRequest request,
+                                 @PathParam("scriptId") String scriptId) {
+        try {
+            getResourceManager().update(request.script, scriptId);
+        } catch (ItemNotFound itemNotFound) {
+            return Response.status(404).build();
+        }
+        return Response.status(204).build();
+    }
+
+    /**
+     * Create script
+     */
+    @POST
+    @Consumes(MediaType.APPLICATION_JSON)
+    public Response saveScript(PigScriptRequest request, @Context HttpServletResponse response,
+                               @Context UriInfo ui) {
+        getResourceManager().create(request.script);
+
+        PigScript script = null;
+
+        try {
+            script = getResourceManager().read(request.script.getId());
+        } catch (ItemNotFound itemNotFound) {
+            return Response.status(404).build();
+        }
+
+        response.setHeader("Location",
+                String.format("%s/%s", ui.getAbsolutePath().toString(), request.script.getId()));
+
+        JSONObject object = new JSONObject();
+        object.put("script", script);
+        return Response.ok(object).status(201).build();
+    }
+
+    public static class PigScriptRequest {
+        public PigScript script;
+    }
+}

http://git-wip-us.apache.org/repos/asf/ambari/blob/5eb22214/contrib/views/pig/src/main/java/org/apache/ambari/view/pig/resources/scripts/models/PigScript.java
----------------------------------------------------------------------
diff --git a/contrib/views/pig/src/main/java/org/apache/ambari/view/pig/resources/scripts/models/PigScript.java b/contrib/views/pig/src/main/java/org/apache/ambari/view/pig/resources/scripts/models/PigScript.java
new file mode 100644
index 0000000..1c69adb
--- /dev/null
+++ b/contrib/views/pig/src/main/java/org/apache/ambari/view/pig/resources/scripts/models/PigScript.java
@@ -0,0 +1,131 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.ambari.view.pig.resources.scripts.models;
+
+import org.apache.ambari.view.pig.persistence.utils.PersonalResource;
+import org.apache.commons.beanutils.BeanUtils;
+
+import java.io.Serializable;
+import java.lang.reflect.InvocationTargetException;
+import java.util.Date;
+import java.util.Map;
+
+/**
+ * Bean to represent script
+ */
+public class PigScript implements Serializable, PersonalResource {
+    String id;
+
+    String title = "";
+    String pigScript = "";
+    String pythonScript = "";
+    String templetonArguments = "";
+    Date dateCreated;
+    String owner = "";
+
+    boolean opened = false;
+
+    public PigScript() {
+    }
+
+    public PigScript(Map<String, Object> stringObjectMap) throws InvocationTargetException, IllegalAccessException {
+        BeanUtils.populate(this, stringObjectMap);
+    }
+
+    @Override
+    public boolean equals(Object o) {
+        if (this == o) return true;
+        if (!(o instanceof PigScript)) return false;
+
+        PigScript pigScript = (PigScript) o;
+
+        if (!id.equals(pigScript.id)) return false;
+
+        return true;
+    }
+
+    @Override
+    public int hashCode() {
+        return id.hashCode();
+    }
+
+    public String getId() {
+        return id;
+    }
+
+    public void setId(String id) {
+        this.id = id;
+    }
+
+    public String getTitle() {
+        return title;
+    }
+
+    public void setTitle(String title) {
+        this.title = title;
+    }
+
+    public String getPigScript() {
+        return pigScript;
+    }
+
+    public void setPigScript(String pigScript) {
+        this.pigScript = pigScript;
+    }
+
+    public String getTempletonArguments() {
+        return templetonArguments;
+    }
+
+    public void setTempletonArguments(String templetonArguments) {
+        this.templetonArguments = templetonArguments;
+    }
+
+    public Date getDateCreated() {
+        return dateCreated;
+    }
+
+    public void setDateCreated(Date dateCreated) {
+        this.dateCreated = dateCreated;
+    }
+
+    public boolean isOpened() {
+        return opened;
+    }
+
+    public void setOpened(boolean opened) {
+        this.opened = opened;
+    }
+
+    public String getOwner() {
+        return owner;
+    }
+
+    public void setOwner(String owner) {
+        this.owner = owner;
+    }
+
+    public String getPythonScript() {
+        return pythonScript;
+    }
+
+    public void setPythonScript(String pythonScript) {
+        this.pythonScript = pythonScript;
+    }
+}

http://git-wip-us.apache.org/repos/asf/ambari/blob/5eb22214/contrib/views/pig/src/main/java/org/apache/ambari/view/pig/resources/udf/UDFResourceManager.java
----------------------------------------------------------------------
diff --git a/contrib/views/pig/src/main/java/org/apache/ambari/view/pig/resources/udf/UDFResourceManager.java b/contrib/views/pig/src/main/java/org/apache/ambari/view/pig/resources/udf/UDFResourceManager.java
new file mode 100644
index 0000000..62e389e
--- /dev/null
+++ b/contrib/views/pig/src/main/java/org/apache/ambari/view/pig/resources/udf/UDFResourceManager.java
@@ -0,0 +1,34 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.ambari.view.pig.resources.udf;
+
+import org.apache.ambari.view.ViewContext;
+import org.apache.ambari.view.pig.resources.PersonalCRUDResourceManager;
+import org.apache.ambari.view.pig.resources.udf.models.UDF;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class UDFResourceManager extends PersonalCRUDResourceManager<UDF> {
+    private final static Logger LOG =
+            LoggerFactory.getLogger(UDFResourceManager.class);
+
+    public UDFResourceManager(ViewContext context) {
+        super(UDF.class, context);
+    }
+}

http://git-wip-us.apache.org/repos/asf/ambari/blob/5eb22214/contrib/views/pig/src/main/java/org/apache/ambari/view/pig/resources/udf/UDFResourceProvider.java
----------------------------------------------------------------------
diff --git a/contrib/views/pig/src/main/java/org/apache/ambari/view/pig/resources/udf/UDFResourceProvider.java b/contrib/views/pig/src/main/java/org/apache/ambari/view/pig/resources/udf/UDFResourceProvider.java
new file mode 100644
index 0000000..3069ddd
--- /dev/null
+++ b/contrib/views/pig/src/main/java/org/apache/ambari/view/pig/resources/udf/UDFResourceProvider.java
@@ -0,0 +1,105 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.ambari.view.pig.resources.udf;
+
+import com.google.inject.Inject;
+import org.apache.ambari.view.*;
+import org.apache.ambari.view.pig.persistence.utils.ItemNotFound;
+import org.apache.ambari.view.pig.persistence.utils.OnlyOwnersFilteringStrategy;
+import org.apache.ambari.view.pig.resources.PersonalCRUDResourceManager;
+import org.apache.ambari.view.pig.resources.udf.models.UDF;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.lang.reflect.InvocationTargetException;
+import java.util.HashSet;
+import java.util.Map;
+import java.util.Set;
+
+public class UDFResourceProvider implements ResourceProvider<UDF> {
+    @Inject
+    ViewContext context;
+
+    protected UDFResourceManager resourceManager = null;
+    protected final static Logger LOG =
+            LoggerFactory.getLogger(UDFResourceProvider.class);
+
+    protected synchronized PersonalCRUDResourceManager<UDF> getResourceManager() {
+        if (resourceManager == null) {
+            resourceManager = new UDFResourceManager(context);
+        }
+        return resourceManager;
+    }
+
+    @Override
+    public UDF getResource(String resourceId, Set<String> properties) throws SystemException, NoSuchResourceException, UnsupportedPropertyException {
+        try {
+            return getResourceManager().read(resourceId);
+        } catch (ItemNotFound itemNotFound) {
+            throw new NoSuchResourceException(resourceId);
+        }
+    }
+
+    @Override
+    public Set<UDF> getResources(ReadRequest readRequest) throws SystemException, NoSuchResourceException, UnsupportedPropertyException {
+        return new HashSet<UDF>(getResourceManager().readAll(
+                new OnlyOwnersFilteringStrategy(this.context.getUsername())));
+    }
+
+    @Override
+    public void createResource(String s, Map<String, Object> stringObjectMap) throws SystemException, ResourceAlreadyExistsException, NoSuchResourceException, UnsupportedPropertyException {
+        UDF udf = null;
+        try {
+            udf = new UDF(stringObjectMap);
+        } catch (InvocationTargetException e) {
+            throw new SystemException("error on creating resource", e);
+        } catch (IllegalAccessException e) {
+            throw new SystemException("error on creating resource", e);
+        }
+        getResourceManager().create(udf);
+    }
+
+    @Override
+    public boolean updateResource(String resourceId, Map<String, Object> stringObjectMap) throws SystemException, NoSuchResourceException, UnsupportedPropertyException {
+        UDF udf = null;
+        try {
+            udf = new UDF(stringObjectMap);
+        } catch (InvocationTargetException e) {
+            throw new SystemException("error on updating resource", e);
+        } catch (IllegalAccessException e) {
+            throw new SystemException("error on updating resource", e);
+        }
+        try {
+            getResourceManager().update(udf, resourceId);
+        } catch (ItemNotFound itemNotFound) {
+            throw new NoSuchResourceException(resourceId);
+        }
+        return true;
+    }
+
+    @Override
+    public boolean deleteResource(String resourceId) throws SystemException, NoSuchResourceException, UnsupportedPropertyException {
+        try {
+            getResourceManager().delete(resourceId);
+        } catch (ItemNotFound itemNotFound) {
+            throw new NoSuchResourceException(resourceId);
+        }
+        return true;
+    }
+}

http://git-wip-us.apache.org/repos/asf/ambari/blob/5eb22214/contrib/views/pig/src/main/java/org/apache/ambari/view/pig/resources/udf/UDFService.java
----------------------------------------------------------------------
diff --git a/contrib/views/pig/src/main/java/org/apache/ambari/view/pig/resources/udf/UDFService.java b/contrib/views/pig/src/main/java/org/apache/ambari/view/pig/resources/udf/UDFService.java
new file mode 100644
index 0000000..d8b24bc
--- /dev/null
+++ b/contrib/views/pig/src/main/java/org/apache/ambari/view/pig/resources/udf/UDFService.java
@@ -0,0 +1,156 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.ambari.view.pig.resources.udf;
+
+import com.google.inject.Inject;
+import org.apache.ambari.view.ViewResourceHandler;
+import org.apache.ambari.view.pig.persistence.utils.ItemNotFound;
+import org.apache.ambari.view.pig.persistence.utils.OnlyOwnersFilteringStrategy;
+import org.apache.ambari.view.pig.resources.PersonalCRUDResourceManager;
+import org.apache.ambari.view.pig.resources.udf.models.UDF;
+import org.apache.ambari.view.pig.services.BaseService;
+import org.json.simple.JSONObject;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import javax.servlet.http.HttpServletResponse;
+import javax.ws.rs.*;
+import javax.ws.rs.core.*;
+import java.util.List;
+
+/**
+ * Servlet for UDFs
+ * API:
+ * GET /
+ *      get all UDFs
+ * GET /:id
+ *      get one UDF
+ * PUT /:id
+ *      update UDF
+ * POST /
+ *      create new UDF
+ *      Required: path, name
+ */
+public class UDFService extends BaseService {
+    @Inject
+    ViewResourceHandler handler;
+
+    protected UDFResourceManager resourceManager = null;
+    protected final static Logger LOG =
+            LoggerFactory.getLogger(UDFService.class);
+
+    protected synchronized PersonalCRUDResourceManager<UDF> getResourceManager() {
+        if (resourceManager == null) {
+            resourceManager = new UDFResourceManager(context);
+        }
+        return resourceManager;
+    }
+
+    /**
+     * Get single item
+     */
+    @GET
+    @Path("{udfId}")
+    @Produces(MediaType.APPLICATION_JSON)
+    public Response getUDF(@PathParam("udfId") String udfId) {
+        UDF udf = null;
+        try {
+            udf = getResourceManager().read(udfId);
+        } catch (ItemNotFound itemNotFound) {
+            return Response.status(404).build();
+        }
+        JSONObject object = new JSONObject();
+        object.put("udf", udf);
+        return Response.ok(object).build();
+    }
+
+    /**
+     * Delete single item
+     */
+    @DELETE
+    @Path("{udfId}")
+    public Response deleteUDF(@PathParam("udfId") String udfId) {
+        try {
+            getResourceManager().delete(udfId);
+        } catch (ItemNotFound itemNotFound) {
+            return Response.status(404).build();
+        }
+        return Response.status(204).build();
+    }
+
+    /**
+     * Get all UDFs
+     */
+    @GET
+    @Produces(MediaType.APPLICATION_JSON)
+    public Response getUDFList(@Context UriInfo ui) {
+        LOG.debug("Getting all UDFs");
+        List allUDFs = getResourceManager().readAll(
+                new OnlyOwnersFilteringStrategy(this.context.getUsername()));
+
+        JSONObject object = new JSONObject();
+        object.put("udfs", allUDFs);
+        return Response.ok(object).build();
+    }
+
+    /**
+     * Update item
+     */
+    @PUT
+    @Path("{udfId}")
+    @Consumes(MediaType.APPLICATION_JSON)
+    public Response updateUDF(UDFRequest request,
+                                 @PathParam("udfId") String udfId) {
+        try {
+            getResourceManager().update(request.udf, udfId);
+        } catch (ItemNotFound itemNotFound) {
+            return Response.status(404).build();
+        }
+        return Response.status(204).build();
+    }
+
+    /**
+     * Create UDF
+     */
+    @POST
+    @Consumes(MediaType.APPLICATION_JSON)
+    public Response createUDF(UDFRequest request, @Context HttpServletResponse response,
+                               @Context UriInfo ui) {
+        getResourceManager().create(request.udf);
+
+        UDF udf = null;
+
+        try {
+            udf = getResourceManager().read(request.udf.getId());
+        } catch (ItemNotFound itemNotFound) {
+            return Response.status(404).build();
+        }
+
+        response.setHeader("Location",
+                String.format("%s/%s", ui.getAbsolutePath().toString(), request.udf.getId()));
+
+        JSONObject object = new JSONObject();
+        object.put("udf", udf);
+        return Response.ok(object).status(201).build();
+    }
+
+    public static class UDFRequest {
+        public UDF udf;
+    }
+}

http://git-wip-us.apache.org/repos/asf/ambari/blob/5eb22214/contrib/views/pig/src/main/java/org/apache/ambari/view/pig/resources/udf/models/UDF.java
----------------------------------------------------------------------
diff --git a/contrib/views/pig/src/main/java/org/apache/ambari/view/pig/resources/udf/models/UDF.java b/contrib/views/pig/src/main/java/org/apache/ambari/view/pig/resources/udf/models/UDF.java
new file mode 100644
index 0000000..0a18329
--- /dev/null
+++ b/contrib/views/pig/src/main/java/org/apache/ambari/view/pig/resources/udf/models/UDF.java
@@ -0,0 +1,79 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.ambari.view.pig.resources.udf.models;
+
+import org.apache.ambari.view.pig.persistence.utils.PersonalResource;
+import org.apache.commons.beanutils.BeanUtils;
+
+import java.io.Serializable;
+import java.lang.reflect.InvocationTargetException;
+import java.util.Map;
+
+/**
+ * Bean to represent User Defined Functions
+ */
+public class UDF implements Serializable, PersonalResource {
+    String id;
+    String path;
+    String name;
+    String owner;
+
+    public UDF() {
+    }
+
+    public UDF(Map<String, Object> stringObjectMap) throws InvocationTargetException, IllegalAccessException {
+        BeanUtils.populate(this, stringObjectMap);
+    }
+
+    @Override
+    public String getId() {
+        return id;
+    }
+
+    @Override
+    public void setId(String id) {
+        this.id = id;
+    }
+
+    @Override
+    public String getOwner() {
+        return owner;
+    }
+
+    @Override
+    public void setOwner(String owner) {
+        this.owner = owner;
+    }
+
+    public String getPath() {
+        return path;
+    }
+
+    public void setPath(String path) {
+        this.path = path;
+    }
+
+    public String getName() {
+        return name;
+    }
+
+    public void setName(String name) {
+        this.name = name;
+    }
+}

http://git-wip-us.apache.org/repos/asf/ambari/blob/5eb22214/contrib/views/pig/src/main/java/org/apache/ambari/view/pig/services/BaseService.java
----------------------------------------------------------------------
diff --git a/contrib/views/pig/src/main/java/org/apache/ambari/view/pig/services/BaseService.java b/contrib/views/pig/src/main/java/org/apache/ambari/view/pig/services/BaseService.java
new file mode 100644
index 0000000..b37c518
--- /dev/null
+++ b/contrib/views/pig/src/main/java/org/apache/ambari/view/pig/services/BaseService.java
@@ -0,0 +1,117 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.ambari.view.pig.services;
+
+import com.google.inject.Inject;
+import org.apache.ambari.view.ViewContext;
+import org.apache.ambari.view.ViewResourceHandler;
+import org.apache.ambari.view.pig.persistence.Storage;
+import org.apache.ambari.view.pig.utils.HdfsApi;
+import org.apache.ambari.view.pig.persistence.utils.StorageUtil;
+import org.json.simple.JSONObject;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import javax.ws.rs.core.MediaType;
+import javax.ws.rs.core.Response;
+import javax.xml.ws.WebServiceException;
+import java.io.IOException;
+import java.util.HashMap;
+
+
+public class BaseService {
+    @Inject
+    protected ViewContext context;
+
+    protected final static Logger LOG =
+            LoggerFactory.getLogger(BaseService.class);
+
+    private Storage storage;
+
+    public Storage getStorage() {
+        if (this.storage == null) {
+            storage = StorageUtil.getStorage(context);
+        }
+        return storage;
+    }
+
+    public void setStorage(Storage storage) {
+        this.storage = storage;
+    }
+
+    private static HdfsApi hdfsApi = null;
+
+    public static HdfsApi getHdfsApi(ViewContext context) {
+        if (hdfsApi == null) {
+            Thread.currentThread().setContextClassLoader(null);
+
+            String userName = context.getUsername();
+
+            String defaultFS = context.getProperties().get("dataworker.defaultFs");
+            if (defaultFS == null) {
+                String message = "dataworker.defaultFs is not configured!";
+                LOG.error(message);
+                throw new WebServiceException(message);
+            }
+
+            try {
+                hdfsApi = new HdfsApi(defaultFS, userName);
+                LOG.info("HdfsApi connected OK");
+            } catch (IOException e) {
+                String message = "HdfsApi IO error: " + e.getMessage();
+                LOG.error(message);
+                throw new WebServiceException(message, e);
+            } catch (InterruptedException e) {
+                String message = "HdfsApi Interrupted error: " + e.getMessage();
+                LOG.error(message);
+                throw new WebServiceException(message, e);
+            }
+        }
+        return hdfsApi;
+    }
+
+    public HdfsApi getHdfsApi()  {
+        return getHdfsApi(context);
+    }
+
+    public static HdfsApi setHdfsApi(HdfsApi api)  {
+        return hdfsApi = api;
+    }
+
+    public static Response badRequestResponse(String message) {
+        HashMap<String, Object> response = new HashMap<String, Object>();
+        response.put("message", message);
+        response.put("status", 400);
+        return Response.status(400).entity(new JSONObject(response)).type(MediaType.APPLICATION_JSON).build();
+    }
+
+    public static Response serverErrorResponse(String message) {
+        HashMap<String, Object> response = new HashMap<String, Object>();
+        response.put("message", message);
+        response.put("status", 500);
+        return Response.status(500).entity(new JSONObject(response)).type(MediaType.APPLICATION_JSON).build();
+    }
+
+    public static Response notFoundResponse(String message) {
+        HashMap<String, Object> response = new HashMap<String, Object>();
+        response.put("message", message);
+        response.put("status", 404);
+        return Response.status(404).entity(new JSONObject(response)).type(MediaType.APPLICATION_JSON).build();
+    }
+}

http://git-wip-us.apache.org/repos/asf/ambari/blob/5eb22214/contrib/views/pig/src/main/java/org/apache/ambari/view/pig/services/HelpService.java
----------------------------------------------------------------------
diff --git a/contrib/views/pig/src/main/java/org/apache/ambari/view/pig/services/HelpService.java b/contrib/views/pig/src/main/java/org/apache/ambari/view/pig/services/HelpService.java
new file mode 100644
index 0000000..c5f1721
--- /dev/null
+++ b/contrib/views/pig/src/main/java/org/apache/ambari/view/pig/services/HelpService.java
@@ -0,0 +1,56 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.ambari.view.pig.services;
+
+import org.apache.ambari.view.ViewContext;
+import org.apache.ambari.view.ViewResourceHandler;
+import org.json.simple.JSONObject;
+
+import javax.ws.rs.GET;
+import javax.ws.rs.Path;
+import javax.ws.rs.Produces;
+import javax.ws.rs.core.*;
+
+public class HelpService extends BaseService {
+    private ViewContext context;
+    private ViewResourceHandler handler;
+
+    public HelpService(ViewContext context, ViewResourceHandler handler) {
+        super();
+        this.context = context;
+        this.handler = handler;
+    }
+
+    @GET
+    @Path("/config")
+    @Produces(MediaType.APPLICATION_JSON)
+    public Response config(){
+        JSONObject object = new JSONObject();
+        String fs = context.getProperties().get("dataworker.defaultFs");
+        object.put("dataworker.defaultFs", fs);
+        return Response.ok(object).build();
+    }
+
+    @GET
+    @Path("/version")
+    @Produces(MediaType.TEXT_PLAIN)
+    public Response version(){
+        return Response.ok("0.0.1-SNAPSHOT").build();
+    }
+}

http://git-wip-us.apache.org/repos/asf/ambari/blob/5eb22214/contrib/views/pig/src/main/java/org/apache/ambari/view/pig/templeton/client/Request.java
----------------------------------------------------------------------
diff --git a/contrib/views/pig/src/main/java/org/apache/ambari/view/pig/templeton/client/Request.java b/contrib/views/pig/src/main/java/org/apache/ambari/view/pig/templeton/client/Request.java
new file mode 100644
index 0000000..de9142f
--- /dev/null
+++ b/contrib/views/pig/src/main/java/org/apache/ambari/view/pig/templeton/client/Request.java
@@ -0,0 +1,213 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.ambari.view.pig.templeton.client;
+
+import com.google.gson.Gson;
+import com.sun.jersey.api.client.ClientResponse;
+import com.sun.jersey.api.client.WebResource;
+import com.sun.jersey.core.util.MultivaluedMapImpl;
+import org.apache.ambari.view.URLStreamProvider;
+import org.apache.ambari.view.ViewContext;
+import org.apache.commons.io.IOUtils;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import javax.ws.rs.core.MediaType;
+import javax.ws.rs.core.UriBuilder;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.StringWriter;
+import java.net.URI;
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ * Request handler, supports GET, POST, PUT, DELETE methods
+ * @param <RESPONSE> data type to deserialize response from JSON
+ */
+public class Request<RESPONSE> {
+    protected final Class<RESPONSE> responseClass;
+    protected final ViewContext context;
+    protected final WebResource resource;
+
+    protected final Gson gson = new Gson();
+
+    protected final static Logger LOG =
+            LoggerFactory.getLogger(Request.class);
+
+    public Request(WebResource resource, Class<RESPONSE> responseClass, ViewContext context) {
+        this.resource = resource;
+        this.responseClass = responseClass;
+        this.context = context;
+    }
+
+    /**
+     * Main implementation of GET request
+     * @param resource resource
+     * @return unmarshalled response data
+     */
+    public RESPONSE get(WebResource resource) throws IOException {
+        LOG.debug("GET " + resource.toString());
+
+        InputStream inputStream = context.getURLStreamProvider().readFrom(resource.toString(), "GET",
+                null, new HashMap<String, String>());
+
+        String responseJson = IOUtils.toString(inputStream);
+        LOG.debug(String.format("RESPONSE => %s", responseJson));
+        return gson.fromJson(responseJson, responseClass);
+    }
+
+    public RESPONSE get() throws IOException {
+        return get(this.resource);
+    }
+
+    public RESPONSE get(MultivaluedMapImpl params) throws IOException {
+        return get(this.resource.queryParams(params));
+    }
+
+    /**
+     * Main implementation of POST request
+     * @param resource resource
+     * @param data post body
+     * @return unmarshalled response data
+     */
+    public RESPONSE post(WebResource resource, MultivaluedMapImpl data) throws IOException {
+        LOG.debug("POST " + resource.toString());
+        LOG.debug("data: " + data.toString());
+
+        UriBuilder builder = UriBuilder.fromPath("host/");
+        for(String key : data.keySet()) {
+            for(String value : data.get(key))
+                builder.queryParam(key, value);
+        }
+
+        if (data != null)
+            LOG.debug("... data: " + builder.build().getRawQuery());
+
+        Map<String, String> headers = new HashMap<String, String>();
+        headers.put("Content-Type", "application/x-www-form-urlencoded");
+
+        InputStream inputStream = context.getURLStreamProvider().readFrom(resource.toString(),
+                "POST", builder.build().getRawQuery(), headers);
+        String responseJson = IOUtils.toString(inputStream);
+
+        LOG.debug(String.format("RESPONSE => %s", responseJson));
+        return gson.fromJson(responseJson, responseClass);
+    }
+
+    public RESPONSE post(MultivaluedMapImpl data) throws IOException {
+        return post(resource, data);
+    }
+
+    public RESPONSE post() throws IOException {
+        return post(resource, new MultivaluedMapImpl());
+    }
+
+    public RESPONSE post(MultivaluedMapImpl params, MultivaluedMapImpl data) throws IOException {
+        return post(resource.queryParams(params), data);
+    }
+
+    public static void main(String[] args) {
+        UriBuilder builder = UriBuilder.fromPath("host/");
+        builder.queryParam("aa", "/tmp/.pigjobs/hue/test111_17-03-2014-16-50-37");
+        System.out.println(builder.build().getRawQuery());
+    }
+
+    /**
+     * Main implementation of PUT request
+     * @param resource resource
+     * @param data put body
+     * @return unmarshalled response data
+     */
+    public RESPONSE put(WebResource resource, MultivaluedMapImpl data) throws IOException {
+        LOG.debug("PUT " + resource.toString());
+
+        UriBuilder builder = UriBuilder.fromPath("host/");
+        for(String key : data.keySet()) {
+            for(String value : data.get(key))
+                builder.queryParam(key, value);
+        }
+
+        if (data != null)
+            LOG.debug("... data: " + builder.build().getRawQuery());
+
+        Map<String, String> headers = new HashMap<String, String>();
+        headers.put("Content-Type", "application/x-www-form-urlencoded");
+
+        InputStream inputStream = context.getURLStreamProvider().readFrom(resource.toString(),
+                "PUT", builder.build().getRawQuery(), headers);
+        String responseJson = IOUtils.toString(inputStream);
+
+        LOG.debug(String.format("RESPONSE => %s", responseJson));
+        return gson.fromJson(responseJson, responseClass);
+    }
+
+    public RESPONSE put(MultivaluedMapImpl data) throws IOException {
+        return put(resource, data);
+    }
+
+    public RESPONSE put() throws IOException {
+        return put(resource, new MultivaluedMapImpl());
+    }
+
+    public RESPONSE put(MultivaluedMapImpl params, MultivaluedMapImpl data) throws IOException {
+        return put(resource.queryParams(params), data);
+    }
+
+    /**
+     * Main implementation of DELETE request
+     * @param resource resource
+     * @param data delete body
+     * @return unmarshalled response data
+     */
+    public RESPONSE delete(WebResource resource, MultivaluedMapImpl data) throws IOException {
+        LOG.debug("DELETE " + resource.toString());
+
+        UriBuilder builder = UriBuilder.fromPath("host/");
+        for(String key : data.keySet()) {
+            for(String value : data.get(key))
+                builder.queryParam(key, value);
+        }
+
+        if (data != null)
+            LOG.debug("... data: " + builder.build().getRawQuery());
+
+        Map<String, String> headers = new HashMap<String, String>();
+        headers.put("Content-Type", "application/x-www-form-urlencoded");
+
+        InputStream inputStream = context.getURLStreamProvider().readFrom(resource.toString(),
+                "DELETE", builder.build().getRawQuery(), headers);
+        String responseJson = IOUtils.toString(inputStream);
+
+        LOG.debug(String.format("RESPONSE => %s", responseJson));
+        return gson.fromJson(responseJson, responseClass);
+    }
+
+    public RESPONSE delete(MultivaluedMapImpl data) throws IOException {
+        return delete(resource, data);
+    }
+
+    public RESPONSE delete() throws IOException {
+        return delete(resource, new MultivaluedMapImpl());
+    }
+
+    public RESPONSE delete(MultivaluedMapImpl params, MultivaluedMapImpl data) throws IOException {
+        return delete(resource.queryParams(params), data);
+    }
+}

http://git-wip-us.apache.org/repos/asf/ambari/blob/5eb22214/contrib/views/pig/src/main/java/org/apache/ambari/view/pig/templeton/client/TempletonApi.java
----------------------------------------------------------------------
diff --git a/contrib/views/pig/src/main/java/org/apache/ambari/view/pig/templeton/client/TempletonApi.java b/contrib/views/pig/src/main/java/org/apache/ambari/view/pig/templeton/client/TempletonApi.java
new file mode 100644
index 0000000..9675a1e
--- /dev/null
+++ b/contrib/views/pig/src/main/java/org/apache/ambari/view/pig/templeton/client/TempletonApi.java
@@ -0,0 +1,164 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.ambari.view.pig.templeton.client;
+
+import com.google.gson.Gson;
+import com.sun.jersey.api.client.Client;
+import com.sun.jersey.api.client.ClientResponse;
+import com.sun.jersey.api.client.WebResource;
+import com.sun.jersey.api.client.config.ClientConfig;
+import com.sun.jersey.api.client.config.DefaultClientConfig;
+import com.sun.jersey.api.json.JSONConfiguration;
+import com.sun.jersey.core.util.MultivaluedMapImpl;
+import org.apache.ambari.view.ViewContext;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import javax.ws.rs.core.MediaType;
+import java.io.File;
+import java.io.IOException;
+import java.util.Map;
+
+//TODO: extract to separate JAR outside ambari-views scope
+/**
+ * Templeton Business Delegate
+ */
+public class TempletonApi {
+    private final Gson gson = new Gson();
+
+    protected final static Logger LOG =
+            LoggerFactory.getLogger(TempletonApi.class);
+
+    protected WebResource service;
+    private String username;
+    private String doAs;
+    private ViewContext context;
+
+    /**
+     * TempletonApi constructor
+     * @param api dataworker.templeton_url
+     * @param username templeton username
+     * @param doAs doAs argument
+     * @param context context with URLStreamProvider
+     */
+    public TempletonApi(String api, String username, String doAs, ViewContext context) {
+        this.username = username;
+        this.doAs = doAs;
+        this.context = context;
+        ClientConfig config = new DefaultClientConfig();
+        config.getFeatures().put(JSONConfiguration.FEATURE_POJO_MAPPING, Boolean.TRUE);
+        Client client = Client.create(config);
+        this.service = client.resource(api);
+    }
+
+    public TempletonApi(String api, String username, ViewContext context) {
+        this(api, username, username, context);
+    }
+
+    /**
+     * Create and queue a Pig job.
+     * @param execute String containing an entire, short pig program to run. (e.g. pwd)
+     * @param pigFile HDFS file name of a pig program to run. (One of either "execute" or "file" is required )
+     * @param statusDir A directory where Templeton will write the status of the Pig job. If
+     *                  provided, it is the caller's responsibility to remove this directory when done.
+     * @param arg Set a program argument. Optional None
+     * @return id A string containing the job ID similar to "job_201110132141_0001".
+     *         info A JSON object containing the information returned when the job was queued.
+     */
+    public JobData runPigQuery(String execute, File pigFile, String statusDir, String arg) throws IOException {
+        MultivaluedMapImpl data = new MultivaluedMapImpl();
+        if (execute != null)
+            data.add("execute", execute);
+        if (pigFile != null)
+            data.add("file", pigFile.toString());
+        if (statusDir != null)
+            data.add("statusdir", statusDir);
+        if (arg != null && !arg.isEmpty()) {
+            for(String arg1 : arg.split("\t")) {
+                data.add("arg", arg1);
+            }
+        }
+
+        TempletonRequest<JobData> request =
+                new TempletonRequest<JobData>(service.path("pig"), JobData.class, username, doAs, context);
+
+        return request.post(data);
+    }
+
+    public JobData runPigQuery(File pigFile, String statusDir, String arg) throws IOException {
+        return runPigQuery(null, pigFile, statusDir, arg);
+    }
+
+    public JobData runPigQuery(String execute, String statusDir, String arg) throws IOException {
+        return runPigQuery(execute, null, statusDir, arg);
+    }
+
+    public JobData runPigQuery(String execute) throws IOException {
+        return runPigQuery(execute, null, null, null);
+    }
+
+    public JobInfo checkJob(String jobId) throws IOException {
+        TempletonRequest<JobInfo> request =
+                new TempletonRequest<JobInfo>(service.path("jobs").path(jobId), JobInfo.class, username, context);
+
+        return request.get();
+    }
+
+    public void killJob(String jobId) throws IOException {
+        TempletonRequest<JobInfo> request =
+                new TempletonRequest<JobInfo>(service.path("jobs").path(jobId), JobInfo.class, username, context);
+
+        try {
+             request.delete();
+        } catch (IOException e) {
+            //TODO: remove this after HIVE-5835 resolved
+            LOG.debug("Ignoring 500 response from webhcat (see HIVE-5835)");
+        }
+    }
+
+    public Status status() throws IOException {
+        TempletonRequest<Status> request =
+                new TempletonRequest<Status>(service.path("status"), Status.class,
+                username, doAs, context);
+        return request.get();
+    }
+
+    public class Status {
+        public String status;
+        public String version;
+    }
+
+    public class JobData {
+        public String id;
+    }
+
+    public class JobInfo {
+        public Map<String, Object> status;
+        public Map<String, Object> profile;
+        public Map<String, Object> userargs;
+
+        public String id;
+        public String parentId;
+        public String percentComplete;
+        public Integer exitValue;
+        public String user;
+        public String callback;
+        public String completed;
+    }
+}

http://git-wip-us.apache.org/repos/asf/ambari/blob/5eb22214/contrib/views/pig/src/main/java/org/apache/ambari/view/pig/templeton/client/TempletonRequest.java
----------------------------------------------------------------------
diff --git a/contrib/views/pig/src/main/java/org/apache/ambari/view/pig/templeton/client/TempletonRequest.java b/contrib/views/pig/src/main/java/org/apache/ambari/view/pig/templeton/client/TempletonRequest.java
new file mode 100644
index 0000000..38ec211
--- /dev/null
+++ b/contrib/views/pig/src/main/java/org/apache/ambari/view/pig/templeton/client/TempletonRequest.java
@@ -0,0 +1,80 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.ambari.view.pig.templeton.client;
+
+import com.sun.jersey.api.client.WebResource;
+import com.sun.jersey.core.util.MultivaluedMapImpl;
+import org.apache.ambari.view.ViewContext;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.io.IOException;
+
+/**
+ * Request handler that adds user.name and doAs
+ * GET parameters to every request
+ * @param <RESPONSE> data type to deserialize response from JSON
+ */
+public class TempletonRequest<RESPONSE> extends Request<RESPONSE> {
+    private String username;
+    private String doAs;
+
+    protected final static Logger LOG =
+            LoggerFactory.getLogger(TempletonRequest.class);
+
+    public TempletonRequest(WebResource resource, Class<RESPONSE> responseClass,
+                            String username, ViewContext context) {
+        this(resource, responseClass, username, username, context);
+    }
+
+    public TempletonRequest(WebResource resource, Class<RESPONSE> responseClass,
+                            String username, String doAs, ViewContext context) {
+        super(resource, responseClass, context);
+        this.username = username;
+        this.doAs = doAs;
+    }
+
+    public RESPONSE get(WebResource resource) throws IOException {
+        MultivaluedMapImpl params = new MultivaluedMapImpl();
+        params.add("user.name", username);
+        params.add("doAs", doAs);
+        return super.get(resource.queryParams(params));
+    }
+
+    public RESPONSE put(WebResource resource, MultivaluedMapImpl data) throws IOException {
+        MultivaluedMapImpl params = new MultivaluedMapImpl();
+        params.add("user.name", username);
+        params.add("doAs", doAs);
+        return super.put(resource.queryParams(params), data);
+    }
+
+    public RESPONSE delete(WebResource resource, MultivaluedMapImpl data) throws IOException {
+        MultivaluedMapImpl params = new MultivaluedMapImpl();
+        params.add("user.name", username);
+        params.add("doAs", doAs);
+        return super.delete(resource.queryParams(params), data);
+    }
+
+    public RESPONSE post(WebResource resource, MultivaluedMapImpl data) throws IOException {
+        MultivaluedMapImpl params = new MultivaluedMapImpl();
+        params.add("user.name", username);
+        params.add("doAs", doAs);
+        return super.post(resource.queryParams(params), data);
+    }
+}

http://git-wip-us.apache.org/repos/asf/ambari/blob/5eb22214/contrib/views/pig/src/main/java/org/apache/ambari/view/pig/utils/FilePaginator.java
----------------------------------------------------------------------
diff --git a/contrib/views/pig/src/main/java/org/apache/ambari/view/pig/utils/FilePaginator.java b/contrib/views/pig/src/main/java/org/apache/ambari/view/pig/utils/FilePaginator.java
new file mode 100644
index 0000000..9312204
--- /dev/null
+++ b/contrib/views/pig/src/main/java/org/apache/ambari/view/pig/utils/FilePaginator.java
@@ -0,0 +1,83 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.ambari.view.pig.utils;
+
+import org.apache.ambari.view.ViewContext;
+import org.apache.ambari.view.pig.services.BaseService;
+import org.apache.hadoop.fs.FSDataInputStream;
+
+import java.io.IOException;
+import java.nio.charset.Charset;
+import java.util.Arrays;
+
+import static java.lang.Math.ceil;
+
+public class FilePaginator {
+    private static int PAGE_SIZE = 1*1024*1024;  // 1MB
+
+    private String filePath;
+    private HdfsApi hdfsApi;
+
+    public FilePaginator(String filePath, ViewContext context) {
+        this.filePath = filePath;
+        hdfsApi = BaseService.getHdfsApi(context);
+    }
+
+    public static void setPageSize(int PAGE_SIZE) {
+        FilePaginator.PAGE_SIZE = PAGE_SIZE;
+    }
+
+    public long pageCount() throws IOException, InterruptedException {
+        return (long)
+                ceil( hdfsApi.getFileStatus(filePath).getLen() / ((double)PAGE_SIZE) );
+    }
+
+    public String readPage(long page) throws IOException, InterruptedException {
+        FSDataInputStream stream = hdfsApi.open(filePath);
+        try {
+            stream.seek(page * PAGE_SIZE);
+        } catch (IOException e) {
+            throw new IllegalArgumentException("Page " + page + " does not exists");
+        }
+
+        byte[] buffer = new byte[PAGE_SIZE];
+        int readCount = 0;
+        int read = 0;
+        while(read < PAGE_SIZE) {
+            try {
+                readCount = stream.read(buffer, read, PAGE_SIZE-read);
+            } catch (IOException e) {
+                stream.close();
+                throw e;
+            }
+            if (readCount == -1)
+                break;
+            read += readCount;
+        }
+        if (read != 0) {
+            byte[] readData = Arrays.copyOfRange(buffer, 0, read);
+            return new String(readData, Charset.forName("UTF-8"));
+        } else {
+            if (page == 0) {
+                return "";
+            }
+            throw new IllegalArgumentException("Page " + page + " does not exists");
+        }
+    }
+}


[2/7] AMBARI-5616 - Ambari Views: Pig view (Roman Rader via tbeerbower)

Posted by tb...@apache.org.
http://git-wip-us.apache.org/repos/asf/ambari/blob/5eb22214/contrib/views/pig/src/main/resources/ui/pig-web/app/templates/pig/util/alert-content.hbs
----------------------------------------------------------------------
diff --git a/contrib/views/pig/src/main/resources/ui/pig-web/app/templates/pig/util/alert-content.hbs b/contrib/views/pig/src/main/resources/ui/pig-web/app/templates/pig/util/alert-content.hbs
new file mode 100644
index 0000000..7c2e370
--- /dev/null
+++ b/contrib/views/pig/src/main/resources/ui/pig-web/app/templates/pig/util/alert-content.hbs
@@ -0,0 +1,22 @@
+{{!
+   Licensed to the Apache Software Foundation (ASF) under one
+   or more contributor license agreements.  See the NOTICE file
+   distributed with this work for additional information
+   regarding copyright ownership.  The ASF licenses this file
+   to you under the Apache License, Version 2.0 (the
+   "License"); you may not use this file except in compliance
+   with the License.  You may obtain a copy of the License at
+  
+       http://www.apache.org/licenses/LICENSE-2.0
+  
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.
+}}
+
+  <button type="button" class="close" >&times;</button>
+  <p>
+    {{view.content.message}}
+  </p>

http://git-wip-us.apache.org/repos/asf/ambari/blob/5eb22214/contrib/views/pig/src/main/resources/ui/pig-web/app/templates/pig/util/alert.hbs
----------------------------------------------------------------------
diff --git a/contrib/views/pig/src/main/resources/ui/pig-web/app/templates/pig/util/alert.hbs b/contrib/views/pig/src/main/resources/ui/pig-web/app/templates/pig/util/alert.hbs
new file mode 100644
index 0000000..8ee2dfb
--- /dev/null
+++ b/contrib/views/pig/src/main/resources/ui/pig-web/app/templates/pig/util/alert.hbs
@@ -0,0 +1,21 @@
+{{!
+   Licensed to the Apache Software Foundation (ASF) under one
+   or more contributor license agreements.  See the NOTICE file
+   distributed with this work for additional information
+   regarding copyright ownership.  The ASF licenses this file
+   to you under the Apache License, Version 2.0 (the
+   "License"); you may not use this file except in compliance
+   with the License.  You may obtain a copy of the License at
+  
+       http://www.apache.org/licenses/LICENSE-2.0
+  
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.
+}}
+
+<div id="alert-wrap">
+   {{view view.alertsView}}
+</div>

http://git-wip-us.apache.org/repos/asf/ambari/blob/5eb22214/contrib/views/pig/src/main/resources/ui/pig-web/app/templates/pig/util/pigHelper.hbs
----------------------------------------------------------------------
diff --git a/contrib/views/pig/src/main/resources/ui/pig-web/app/templates/pig/util/pigHelper.hbs b/contrib/views/pig/src/main/resources/ui/pig-web/app/templates/pig/util/pigHelper.hbs
new file mode 100644
index 0000000..4840931
--- /dev/null
+++ b/contrib/views/pig/src/main/resources/ui/pig-web/app/templates/pig/util/pigHelper.hbs
@@ -0,0 +1,34 @@
+{{!
+   Licensed to the Apache Software Foundation (ASF) under one
+   or more contributor license agreements.  See the NOTICE file
+   distributed with this work for additional information
+   regarding copyright ownership.  The ASF licenses this file
+   to you under the Apache License, Version 2.0 (the
+   "License"); you may not use this file except in compliance
+   with the License.  You may obtain a copy of the License at
+  
+       http://www.apache.org/licenses/LICENSE-2.0
+  
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.
+}}
+
+<button type="button" class="btn btn-default dropdown-toggle" data-toggle="dropdown">
+  {{t 'editor.pighelper'}}
+  <span class="caret"></span>
+</button>
+<ul class="dropdown-menu" id="pig_helper">
+  {{#each view.helpers}}
+    <li class="dropdown-submenu">
+      <a>{{this.title}}</a>
+      <ul class="dropdown-menu">
+        {{#each this.helpers }}
+          <li><a href="#" {{action 'putToEditor' this target="view" }} >{{this}}</a></li>
+        {{/each}}
+      </ul>
+    </li>
+  {{/each}}
+</ul>

http://git-wip-us.apache.org/repos/asf/ambari/blob/5eb22214/contrib/views/pig/src/main/resources/ui/pig-web/app/templates/pig/util/script-nav.hbs
----------------------------------------------------------------------
diff --git a/contrib/views/pig/src/main/resources/ui/pig-web/app/templates/pig/util/script-nav.hbs b/contrib/views/pig/src/main/resources/ui/pig-web/app/templates/pig/util/script-nav.hbs
new file mode 100644
index 0000000..767ad5f
--- /dev/null
+++ b/contrib/views/pig/src/main/resources/ui/pig-web/app/templates/pig/util/script-nav.hbs
@@ -0,0 +1,30 @@
+{{!
+   Licensed to the Apache Software Foundation (ASF) under one
+   or more contributor license agreements.  See the NOTICE file
+   distributed with this work for additional information
+   regarding copyright ownership.  The ASF licenses this file
+   to you under the Apache License, Version 2.0 (the
+   "License"); you may not use this file except in compliance
+   with the License.  You may obtain a copy of the License at
+  
+       http://www.apache.org/licenses/LICENSE-2.0
+  
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.
+}}
+
+<span class='lb' {{action "gotoSection" view.content }}>
+{{view.content.label}}
+
+{{#unless view.content.label}}
+...     
+{{/unless}} 
+	
+</span>
+  
+{{#if view.content.id}} 
+  <button {{action "close" view.content }}type="button" class="close rm" >&times;</button>
+{{/if}}

http://git-wip-us.apache.org/repos/asf/ambari/blob/5eb22214/contrib/views/pig/src/main/resources/ui/pig-web/app/translations.js
----------------------------------------------------------------------
diff --git a/contrib/views/pig/src/main/resources/ui/pig-web/app/translations.js b/contrib/views/pig/src/main/resources/ui/pig-web/app/translations.js
new file mode 100644
index 0000000..6efff8e
--- /dev/null
+++ b/contrib/views/pig/src/main/resources/ui/pig-web/app/translations.js
@@ -0,0 +1,110 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+Ember.I18n.translations = {
+  'common':{
+    'create': 'Create',
+    'add':"Add",
+    'edit':"Edit",
+    'name':"Name",
+    'path':"Path",
+    'owner':"Owner",
+    'delete':"Delete",
+    'created':"Created",
+    'created':"Created",
+    'history':"History",
+    'clone':"Clone",
+    'cancel':"Cancel"
+  },
+  'scripts':{
+    'scripts':"Scripts",
+    'newscript': "New Script",
+    'title': "Title",
+    'modal':{
+      'create_script':'Create script',
+      'file_path_placeholder':'Full path to script file',
+      'file_path_hint':'Leave empty to create file automatically.',
+      'file_path_hint':'Leave empty to create file automatically.',
+
+      'confirm_delete':'Confirm Delete',
+      'confirm_delete_massage':'Are you sure you want to delete {{title}} script?'
+    },
+    'alert':{
+      'arg_present':'Argument already present',
+      'file_exist_error':'File already exist',
+      'script_saved':'{{title}} saved!',
+      'script_created':'{{title}} created!',
+      'script_deleted':'{{title}} deleted!',
+      'create_failed':'Failed to create script!',
+      'delete_failed':'Delete failed!',
+      'save_error':'Error while saving script',
+      'save_error_reason':'{{message}}',
+    },
+  },
+  'editor':{
+    'pighelper':'PIG helper',
+    'udfhelper':'UDF helper',
+    'save':'Save',
+    'execute':'Execute',
+    'explain':'Explain',
+    'syntax_check':'Syntax check'
+  },
+  'job':{
+    'title': "Title",
+    'results':'Results',
+    'logs':'Logs',
+    'job_status':'Job status: ',
+    'status':'Status',
+    'started':'Started',
+    'alert':{
+      'job_started' :'Job started!',
+      'job_killed' :'{{title}} job killed!',
+      'job_kill_error' :'Job kill failed!',
+      'start_filed' :'Job failed to start!',
+      'load_error' :'Error loading job. Reason: {{message}}',
+      'stdout_error' :'Error loading STDOUT. \n Status: {{status}} Message: {{message}}',
+      'stderr_error' :'Error loading STDERR. \n Status: {{status}} Message: {{message}}',
+      'exit_error' :'Error loading EXITCODE. \n Status: {{status}} Message: {{message}}',
+    },
+    'job_results':{
+      'stdout':'Stdout',
+      'stderr':'Stderr',
+      'exitcode':'Exit code',
+      'stdout_loading':'Loading stdout...',
+      'stderr_loading':'Loading stderr...',
+      'exitcode_loading':'Loading exitcode...',
+    },
+  },
+  'udfs':{
+    'udfs':'UDFs',
+    'tooltips':{
+      'path':'Path of this script file on HDFS',
+    },
+    'alert':{
+      'udf_created':'{{name}} created!',
+      'udf_deleted':'{{name}} deleted!',
+      'create_failed':'Failed to create UDF!',
+      'delete_failed':'Delete failed!',
+    },
+    'modal':{
+      'create_udf':'Create UDF',
+      'udf_name':'UDF name',
+      'hdfs_path':'HDFS path',
+    }
+  }
+};

http://git-wip-us.apache.org/repos/asf/ambari/blob/5eb22214/contrib/views/pig/src/main/resources/ui/pig-web/app/views/pig.js
----------------------------------------------------------------------
diff --git a/contrib/views/pig/src/main/resources/ui/pig-web/app/views/pig.js b/contrib/views/pig/src/main/resources/ui/pig-web/app/views/pig.js
new file mode 100644
index 0000000..869eecb
--- /dev/null
+++ b/contrib/views/pig/src/main/resources/ui/pig-web/app/views/pig.js
@@ -0,0 +1,59 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+var App = require('app');
+
+App.PigView = Em.View.extend({
+  selectedBinding: 'controller.category',
+  navs: Ember.computed(function() {
+    var items = [ 
+      {name:'scripts',url:'pig.scriptList',label: Em.I18n.t('scripts.scripts')},
+      {name:'udfs',url:'pig.udfs',label:Em.I18n.t('udfs.udfs')},
+      {name:'history',url:'pig.history',label:Em.I18n.t('common.history')}
+    ];
+    this.get('controller.openScripts').forEach(function(scripts){
+      items.push(scripts);
+    });
+    return items;
+  }).property('controller.openScripts'),
+  navItemsView : Ember.CollectionView.extend({
+    classNames: ['list-group'],
+    tagName: 'div',
+    content: function () { 
+      return this.get('parentView.navs')
+    }.property('parentView.navs'),
+    itemViewClass: Ember.View.extend(Ember.ViewTargetActionSupport,{
+      tagName: 'a',
+      templateName: 'pig/util/script-nav',
+      classNames: ['list-group-item pig-nav-item'],
+      classNameBindings: ['isActive:active'],
+      action: 'gotoSection',
+      click: function(e) {
+        if (e.target.type=="button") {
+          return false;
+        };
+        this.triggerAction({
+          actionContext:this.content
+        }); 
+      },
+      isActive: function () {
+        return this.get('content.name') === this.get('parentView.parentView.selected');
+      }.property('content.name', 'parentView.parentView.selected')
+    })
+  })
+});

http://git-wip-us.apache.org/repos/asf/ambari/blob/5eb22214/contrib/views/pig/src/main/resources/ui/pig-web/app/views/pig/jobResults.js
----------------------------------------------------------------------
diff --git a/contrib/views/pig/src/main/resources/ui/pig-web/app/views/pig/jobResults.js b/contrib/views/pig/src/main/resources/ui/pig-web/app/views/pig/jobResults.js
new file mode 100644
index 0000000..15bf89b
--- /dev/null
+++ b/contrib/views/pig/src/main/resources/ui/pig-web/app/views/pig/jobResults.js
@@ -0,0 +1,52 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+var App = require('app');
+
+App.JobResultsView = Em.View.extend({
+    templateName: 'pig/jobResults',
+    outputView: Em.View.extend({
+      classNames: ['panel panel-default panel-results'],
+      templateName: 'pig/jobResultsOutput',
+      didInsertElement:function () {
+          $('#btn-stdout').button({'loadingText':Em.I18n.t('job.job_results.stdout_loading')});
+          $('#btn-stderr').button({'loadingText':Em.I18n.t('job.job_results.stderr_loading')});
+          $('#btn-exitcode').button({'loadingText':Em.I18n.t('job.job_results.exitcode_loading')});
+      },
+      actions:{
+        getOutput:function (item) {
+          var self = this;
+          var controller = this.get('controller');
+          output = controller.get(item); 
+          if (!output) {
+            return;
+          };
+          $(this.get('element')).find('.btn').removeClass('active');
+          $('#btn-'+item).button('loading');
+          this.set('isLoadingOutput',true);
+          output.then(function (result) {
+            $('#btn-'+item).button('reset').addClass('active');
+            self.set('isLoadingOutput',false);
+            self.set('activeOutput',result.fileContent);
+          })
+        }
+      },
+      isLoadingOutput:false,
+      activeOutput:'Select output.'
+    })
+});

http://git-wip-us.apache.org/repos/asf/ambari/blob/5eb22214/contrib/views/pig/src/main/resources/ui/pig-web/app/views/pig/modal/confirmDelete.js
----------------------------------------------------------------------
diff --git a/contrib/views/pig/src/main/resources/ui/pig-web/app/views/pig/modal/confirmDelete.js b/contrib/views/pig/src/main/resources/ui/pig-web/app/views/pig/modal/confirmDelete.js
new file mode 100644
index 0000000..f8e59d1
--- /dev/null
+++ b/contrib/views/pig/src/main/resources/ui/pig-web/app/views/pig/modal/confirmDelete.js
@@ -0,0 +1,29 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+var App = require('app');
+
+App.ConfirmDeleteView = App.PigModalView.extend({
+  templateName:'pig/modal/confirmdelete',
+  actions:{
+    confirm:function(script) {
+      $(this.get('element')).find('.modal').modal('hide');
+      return this.controller.send('confirmdelete',script);
+    }
+  },
+});

http://git-wip-us.apache.org/repos/asf/ambari/blob/5eb22214/contrib/views/pig/src/main/resources/ui/pig-web/app/views/pig/modal/createScript.js
----------------------------------------------------------------------
diff --git a/contrib/views/pig/src/main/resources/ui/pig-web/app/views/pig/modal/createScript.js b/contrib/views/pig/src/main/resources/ui/pig-web/app/views/pig/modal/createScript.js
new file mode 100644
index 0000000..cf4e412
--- /dev/null
+++ b/contrib/views/pig/src/main/resources/ui/pig-web/app/views/pig/modal/createScript.js
@@ -0,0 +1,34 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+var App = require('app');
+
+App.CreateScriptView = App.PigModalView.extend({
+  templateName: 'pig/modal/createScript',
+  actions:{
+    create: function(script) {
+      var filePath = this.controller.get('filePath');
+      $(this.get('element')).find('.modal').modal('hide');
+      return this.controller.send('confirmcreate',script,filePath);
+    },
+    close:function (script) {
+      script.deleteRecord();
+      return this._super();
+    }
+  }
+});

http://git-wip-us.apache.org/repos/asf/ambari/blob/5eb22214/contrib/views/pig/src/main/resources/ui/pig-web/app/views/pig/modal/createUdf.js
----------------------------------------------------------------------
diff --git a/contrib/views/pig/src/main/resources/ui/pig-web/app/views/pig/modal/createUdf.js b/contrib/views/pig/src/main/resources/ui/pig-web/app/views/pig/modal/createUdf.js
new file mode 100644
index 0000000..22ed431
--- /dev/null
+++ b/contrib/views/pig/src/main/resources/ui/pig-web/app/views/pig/modal/createUdf.js
@@ -0,0 +1,38 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+var App = require('app');
+
+App.CreateUdfView = App.PigModalView.extend({
+  templateName: 'pig/modal/createUdf',
+  actions:{
+    createUdf: function(udf) {
+      $(this.get('element')).find('.modal').modal('hide');
+      return this.controller.send('createUdf',udf);
+    },
+    close:function (udf) {
+      udf.deleteRecord();
+      return this._super();
+    }
+  },
+  udfInvalid:function (argument) {
+    var udf = this.get('controller.content');
+    var invalid = !udf.get('name') || !udf.get('path');
+    return invalid;
+  }.property('controller.content.name','controller.content.path'),
+});

http://git-wip-us.apache.org/repos/asf/ambari/blob/5eb22214/contrib/views/pig/src/main/resources/ui/pig-web/app/views/pig/modal/pigModal.js
----------------------------------------------------------------------
diff --git a/contrib/views/pig/src/main/resources/ui/pig-web/app/views/pig/modal/pigModal.js b/contrib/views/pig/src/main/resources/ui/pig-web/app/views/pig/modal/pigModal.js
new file mode 100644
index 0000000..d86e9fe
--- /dev/null
+++ b/contrib/views/pig/src/main/resources/ui/pig-web/app/views/pig/modal/pigModal.js
@@ -0,0 +1,35 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+var App = require('app');
+
+App.PigModalView = Ember.View.extend({
+  actions:{
+    close:function() {
+      return $(this.get('element')).find('.modal').modal('hide');
+    }
+  },
+  didInsertElement: function() {
+    var view = this;
+    $(this.get('element')).find('.modal').modal('show');
+    return this.$('.modal').on("hidden.bs.modal", function(ev) {
+      view.controller.send('closeModal');
+    });
+  },
+  layoutName:'pig/modal/modalLayout'
+});

http://git-wip-us.apache.org/repos/asf/ambari/blob/5eb22214/contrib/views/pig/src/main/resources/ui/pig-web/app/views/pig/pigHistory.js
----------------------------------------------------------------------
diff --git a/contrib/views/pig/src/main/resources/ui/pig-web/app/views/pig/pigHistory.js b/contrib/views/pig/src/main/resources/ui/pig-web/app/views/pig/pigHistory.js
new file mode 100644
index 0000000..1ee56a5
--- /dev/null
+++ b/contrib/views/pig/src/main/resources/ui/pig-web/app/views/pig/pigHistory.js
@@ -0,0 +1,36 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+var App = require('app');
+
+App.PigHistoryView = Em.View.extend({
+  historyTableRow:Ember.View.extend({
+    statuses:{
+      'SUBMITTING':'success',
+      'SUBMITTED':'success',
+      'RUNNING':'warning',
+      'COMPLETED':'success',
+      'SUBMIT_FAILED':'danger',
+      'KILLED':'danger',
+      'FAILED':'danger'
+    },
+    labelClass:function () {
+      return 'label-'+this.statuses[this.get('context.status')];
+    }.property('context.status'),
+  })
+});

http://git-wip-us.apache.org/repos/asf/ambari/blob/5eb22214/contrib/views/pig/src/main/resources/ui/pig-web/app/views/pig/pigJob.js
----------------------------------------------------------------------
diff --git a/contrib/views/pig/src/main/resources/ui/pig-web/app/views/pig/pigJob.js b/contrib/views/pig/src/main/resources/ui/pig-web/app/views/pig/pigJob.js
new file mode 100644
index 0000000..09d17dc
--- /dev/null
+++ b/contrib/views/pig/src/main/resources/ui/pig-web/app/views/pig/pigJob.js
@@ -0,0 +1,41 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+var App = require('app');
+
+App.PigJobView = Em.View.extend({
+    templateName: 'pig/job',
+    classNames:['job-status-view'],
+    actions:{
+      editJob:function (job) {
+        job.store.createRecord('job',{pigScript: job.get('pigScript'),title:job.get('title')});
+        return 
+      }
+    },
+    progressBar: Em.View.extend({
+      classNames:['progress'],
+      didInsertElement:function () {
+        this.update();
+      },
+      update:function () {
+        var progress = (!this.get('content.isTerminated'))?this.get('content.percentStatus'):100;
+        $(this.get('element')).find('.progress-bar').css('width',progress+'%');
+      }.observes('content.percentStatus'),
+      template:Em.Handlebars.compile('<div {{bind-attr class=":progress-bar content.isTerminated:progress-bar-danger:progress-bar-success" }}role="progressbar"></div>')
+    })
+});

http://git-wip-us.apache.org/repos/asf/ambari/blob/5eb22214/contrib/views/pig/src/main/resources/ui/pig-web/app/views/pig/pigUdfs.js
----------------------------------------------------------------------
diff --git a/contrib/views/pig/src/main/resources/ui/pig-web/app/views/pig/pigUdfs.js b/contrib/views/pig/src/main/resources/ui/pig-web/app/views/pig/pigUdfs.js
new file mode 100644
index 0000000..81bc4f6
--- /dev/null
+++ b/contrib/views/pig/src/main/resources/ui/pig-web/app/views/pig/pigUdfs.js
@@ -0,0 +1,23 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+var App = require('app');
+
+App.PigUdfsView = Em.View.extend({
+    templateName: 'pig/udfs'
+});

http://git-wip-us.apache.org/repos/asf/ambari/blob/5eb22214/contrib/views/pig/src/main/resources/ui/pig-web/app/views/pig/scriptEdit.js
----------------------------------------------------------------------
diff --git a/contrib/views/pig/src/main/resources/ui/pig-web/app/views/pig/scriptEdit.js b/contrib/views/pig/src/main/resources/ui/pig-web/app/views/pig/scriptEdit.js
new file mode 100644
index 0000000..a352e35
--- /dev/null
+++ b/contrib/views/pig/src/main/resources/ui/pig-web/app/views/pig/scriptEdit.js
@@ -0,0 +1,257 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+var App = require('app');
+
+App.PigScriptEditView = Em.View.extend({
+  didInsertElement:function () {
+    $('.file-path').tooltip();
+    if (this.get('controller.isJob')) {
+      this.set('isEditConfirmed',false);
+    };
+  },
+  actions:{
+    insertUdf:function (udf) {
+      var cm = this.get('codeMirror');
+      cm.setValue('REGISTER ' + udf.get('path') + '\n'+ cm.getValue());
+    },
+    confirmEdit:function () {
+      this.set('isEditConfirmed', true);
+    }
+  },
+  argumentInput: Ember.TextField.extend({
+    viewName:"argumentInput",
+    actions:{
+      sendArgument:function(){
+        this.get('parentView.controller').send('addArgument',this.get('value'));
+        this.set('value',null);
+      }
+    },
+    classNames:["form-control argadd"],
+    keyPress:function  (event) {
+      if (event.keyCode=="13") {
+        this.send('sendArgument');
+      }
+    }
+  }),
+  showEditor:function () {
+    var wrapper = $('.editor-container');
+    return (this.get('controller.category')=='results')?$(wrapper).hide():$(wrapper).show();;
+  }.observes('controller.category','codeMirror'),
+  codeMirror:null,
+  codeMirrorView: Ember.TextArea.extend({
+    valueBinding:"content.fileContent",
+    updateCM:function (view,trigger) {
+      var cm = this.get('parentView.codeMirror');
+      var cmElement = $(cm.display.wrapper);
+      if (this.get('content.isLoaded')) {
+        if (this.get('parentView.controller.isJob') && !this.get('parentView.isEditConfirmed')) {
+          cm.setOption('readOnly',true);
+          cmElement.addClass('inactive');
+        } else {
+          cm.setOption('readOnly',false);
+          cmElement.removeClass('inactive')
+        }
+        this.get('parentView.codeMirror').setValue(this.get('content.fileContent')||'');
+      } else {
+        cm.setOption('readOnly',true);
+        cmElement.addClass('inactive');
+      };
+
+    }.observes('parentView.codeMirror', 'content.didLoad', 'parentView.isEditConfirmed'),
+    didInsertElement: function() {
+      var self = this;
+      var cm = CodeMirror.fromTextArea(this.get('element'),{
+        lineNumbers: true,
+        matchBrackets: true,
+        indentUnit: 4,
+        keyMap: "emacs"
+      });
+      this.set('parentView.codeMirror',cm);
+      cm.on('change',function (cm) {
+        var pig_script = self.get('content');
+        if (pig_script.get('isLoaded')){
+          pig_script.set('fileContent',cm.getValue());
+        }
+      });                  
+    }
+  }),
+  isEditConfirmed: true,
+  pigHelperView: Em.View.extend({
+    actions:{
+      putToEditor:function (helper) {
+        helper = helper.toString();
+        
+        var editor = this.get('parentView.codeMirror');
+        var cursor = editor.getCursor();
+        var pos = this.findPosition(helper);
+        
+        editor.replaceRange(helper, cursor, cursor);
+        editor.focus();
+
+        if (pos.length>1) {
+          editor.setSelection(
+            {line:cursor.line, ch:cursor.ch + pos[0]},
+            {line:cursor.line, ch:cursor.ch + pos[1]+1}
+          );
+        }
+
+        return false;
+      }
+    },
+    findPosition: function (curLine){
+      var pos= curLine.indexOf("%");
+      var posArr=[];
+      while(pos > -1) {
+        posArr.push(pos);
+        pos = curLine.indexOf("%", pos+1);
+      }
+      return posArr;
+    },
+    templateName:'pig/util/pigHelper',
+    helpers:[
+      {
+        'title':'Eval Functions',
+        'helpers':[
+          'AVG(%VAR%)',
+          'CONCAT(%VAR1%, %VAR2%)',
+          'COUNT(%VAR%)',
+          'COUNT_START(%VAR%)',
+          'IsEmpty(%VAR%)',
+          'DIFF(%VAR1%, %VAR2%)',
+          'MAX(%VAR%)',
+          'MIN(%VAR%)',
+          'SIZE(%VAR%)',
+          'SUM(%VAR%)',
+          'TOKENIZE(%VAR%, %DELIM%)',
+        ]
+      },
+      {
+        'title':'Relational Operators',
+        'helpers':[
+          'COGROUP %VAR% BY %VAR%',
+          'CROSS %VAR1%, %VAR2%;',
+          'DISTINCT %VAR%;',
+          'FILTER %VAR% BY %COND%',
+          'FLATTEN(%VAR%)',
+          'FOREACH %DATA% GENERATE %NEW_DATA%',
+          'FOREACH %DATA% {%NESTED_BLOCK%}',
+          'GROUP %VAR% BY %VAR%',
+          'GROUP %VAR% ALL',
+          'JOIN %VAR% BY ',
+          'LIMIT %VAR% %N%',
+          'ORDER %VAR% BY %FIELD%',
+          'SAMPLE %VAR% %SIZE%',
+          'SPLIT %VAR1% INTO %VAR2% IF %EXPRESSIONS%',
+          'UNION %VAR1%, %VAR2%',
+        ]
+      },
+      {
+        'title':'I/0',
+        'helpers':[
+          "LOAD '%FILE%';",
+          'DUMP %VAR%;',
+          'STORE %VAR% INTO %PATH%;',
+        ]
+      },
+      {
+        'title':'Debug',
+        'helpers':[
+          'EXPLAIN %VAR%;',
+          'ILLUSTRATE %VAR%;',
+          'DESCRIBE %VAR%;',
+        ]
+      },
+      {
+        'title':'HCatalog',
+        'helpers':[
+          "LOAD '%TABLE%' USING org.apache.hcatalog.pig.HCatLoader();",
+        ]
+      },
+      {
+        'title':'Math',
+        'helpers':[
+          'ABS(%VAR%)',
+          'ACOS(%VAR%)',
+          'ASIN(%VAR%)',
+          'ATAN(%VAR%)',
+          'CBRT(%VAR%)',
+          'CEIL(%VAR%)',
+          'COS(%VAR%)',
+          'COSH(%VAR%)',
+          'EXP(%VAR%)',
+          'FLOOR(%VAR%)',
+          'LOG(%VAR%)',
+          'LOG10(%VAR%)',
+          'RANDOM(%VAR%)',
+          'ROUND(%VAR%)',
+          'SIN(%VAR%)',
+          'SINH(%VAR%)',
+          'SQRT(%VAR%)',
+          'TAN(%VAR%)',
+          'TANH(%VAR%)',
+        ]
+      },
+      {
+        'title':'Tuple, Bag, Map Functions',
+        'helpers':[
+          'TOTUPLE(%VAR%)',
+          'TOBAG(%VAR%)',
+          'TOMAP(%KEY%, %VALUE%)',
+          'TOP(%topN%, %COLUMN%, %RELATION%)',
+        ]
+      },
+      {
+        'title':'String Functions',
+        'helpers':[
+          "INDEXOF(%STRING%, '%CHARACTER%', %STARTINDEX%)",
+          "LAST_INDEX_OF(%STRING%, '%CHARACTER%', %STARTINDEX%)",
+          "LOWER(%STRING%)",
+          "REGEX_EXTRACT(%STRING%, %REGEX%, %INDEX%)",
+          "REGEX_EXTRACT_ALL(%STRING%, %REGEX%)",
+          "REPLACE(%STRING%, '%oldChar%', '%newChar%')",
+          "STRSPLIT(%STRING%, %REGEX%, %LIMIT%)",
+          "SUBSTRING(%STRING%, %STARTINDEX%, %STOPINDEX%)",
+          "TRIM(%STRING%)",
+          "UCFIRST(%STRING%)",
+          "UPPER(%STRING%)",
+        ]
+      },
+      {
+        'title':'Macros',
+        'helpers':[
+          "IMPORT '%PATH_TO_MACRO%';",
+        ]
+      },
+      {
+        'title':'HBase',
+        'helpers':[
+          "LOAD 'hbase://%TABLE%' USING org.apache.pig.backend.hadoop.hbase.HBaseStorage('%columnList%')",
+          "STORE %VAR% INTO 'hbase://%TABLE%' USING org.apache.pig.backend.hadoop.hbase.HBaseStorage('%columnList%')",
+        ]
+      },
+      {
+        'title':'Python UDF',
+        'helpers':[
+          "REGISTER 'python_udf.py' USING jython AS myfuncs;",
+        ]
+      }
+    ]
+  }),
+  pigParamView:Em.TextField.extend({})
+});

http://git-wip-us.apache.org/repos/asf/ambari/blob/5eb22214/contrib/views/pig/src/main/resources/ui/pig-web/app/views/pig/scriptList.js
----------------------------------------------------------------------
diff --git a/contrib/views/pig/src/main/resources/ui/pig-web/app/views/pig/scriptList.js b/contrib/views/pig/src/main/resources/ui/pig-web/app/views/pig/scriptList.js
new file mode 100644
index 0000000..50e5a95
--- /dev/null
+++ b/contrib/views/pig/src/main/resources/ui/pig-web/app/views/pig/scriptList.js
@@ -0,0 +1,22 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+var App = require('app');
+
+App.PigScriptListView = Em.View.extend({
+});

http://git-wip-us.apache.org/repos/asf/ambari/blob/5eb22214/contrib/views/pig/src/main/resources/ui/pig-web/app/views/pig/scriptResults.js
----------------------------------------------------------------------
diff --git a/contrib/views/pig/src/main/resources/ui/pig-web/app/views/pig/scriptResults.js b/contrib/views/pig/src/main/resources/ui/pig-web/app/views/pig/scriptResults.js
new file mode 100644
index 0000000..cb9f52c
--- /dev/null
+++ b/contrib/views/pig/src/main/resources/ui/pig-web/app/views/pig/scriptResults.js
@@ -0,0 +1,23 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+var App = require('app');
+
+App.PigScriptResultsView = Em.View.extend({
+
+});

http://git-wip-us.apache.org/repos/asf/ambari/blob/5eb22214/contrib/views/pig/src/main/resources/ui/pig-web/app/views/pig/scriptResultsNav.js
----------------------------------------------------------------------
diff --git a/contrib/views/pig/src/main/resources/ui/pig-web/app/views/pig/scriptResultsNav.js b/contrib/views/pig/src/main/resources/ui/pig-web/app/views/pig/scriptResultsNav.js
new file mode 100644
index 0000000..a9dd420
--- /dev/null
+++ b/contrib/views/pig/src/main/resources/ui/pig-web/app/views/pig/scriptResultsNav.js
@@ -0,0 +1,49 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+var App = require('app');
+
+App.PigScriptResultsNavView = Em.View.extend({
+  tagName:'span',
+  selectedBinding: 'controller.category',
+  navResultsView : Ember.CollectionView.extend({
+    classNames: ['nav nav-pills nav-results pull-right'],
+    tagName: 'ul',
+    content: function () { 
+      var navs = [ 
+        {name:'edit',route:'job',label:Em.I18n.t('common.edit')},
+        {name:'results',route:'job.results',label:Em.I18n.t('job.results')},
+        //{name:'logs',route:'#',label:Em.I18n.t('job.logs')}
+      ];
+      return navs;
+    }.property(),
+    itemViewClass: Ember.View.extend(Ember.ViewTargetActionSupport,{
+      actions:{
+        switch:function (argument) {
+          return this.send('navigate',argument)
+        }
+      },
+      tagName: 'li',
+      template: Ember.Handlebars.compile('<a href="#" {{action "switch" view.content target="view"}} >{{view.content.label}}</a>'),
+      classNameBindings: ['isActive:active'],
+      isActive: function () {
+        return this.get('content.name') === this.get('parentView.parentView.selected');
+      }.property('content.name', 'parentView.parentView.selected')
+    })
+  })
+});

http://git-wip-us.apache.org/repos/asf/ambari/blob/5eb22214/contrib/views/pig/src/main/resources/ui/pig-web/app/views/pig/util/pigUtilAlert.js
----------------------------------------------------------------------
diff --git a/contrib/views/pig/src/main/resources/ui/pig-web/app/views/pig/util/pigUtilAlert.js b/contrib/views/pig/src/main/resources/ui/pig-web/app/views/pig/util/pigUtilAlert.js
new file mode 100644
index 0000000..10e2345
--- /dev/null
+++ b/contrib/views/pig/src/main/resources/ui/pig-web/app/views/pig/util/pigUtilAlert.js
@@ -0,0 +1,55 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+var App = require('app');
+
+App.PigUtilAlertView = Ember.View.extend({ 
+  alertsView : Ember.CollectionView.extend({
+    content: function () { 
+      return this.get('controller.content');
+    }.property('controller.content'),
+    itemViewClass: Ember.View.extend({
+      classNames: ['alert fade in'],
+      classNameBindings: ['alertClass'],
+      attributeBindings:['dismiss:data-dismiss'],
+      dismiss:'alert',
+      templateName: 'pig/util/alert-content',
+      didInsertElement:function () {
+        var self = this;
+        
+        $(self.get('element')).bind('closed.bs.alert', function (e) {
+          return self.clearAlert();
+        });
+
+        if (this.get('content.status')!='error') {
+          Ember.run.debounce(self, self.close, 3000);
+        };
+      },
+      close : function (argument) {
+        return $(this.get('element')).alert('close');
+      },
+      clearAlert:function () {
+        return this.get('controller').send('removeAlertObject',this.content);
+      },
+      alertClass: function () {
+        var classes = {'success':'alert-success','error':'alert-danger','info':'alert-info'};
+        return classes[this.get('content.status')];
+      }.property('content.status')
+    })
+  })
+});

http://git-wip-us.apache.org/repos/asf/ambari/blob/5eb22214/contrib/views/pig/src/main/resources/ui/pig-web/bin
----------------------------------------------------------------------
diff --git a/contrib/views/pig/src/main/resources/ui/pig-web/bin b/contrib/views/pig/src/main/resources/ui/pig-web/bin
new file mode 100644
index 0000000..d9eb09e
--- /dev/null
+++ b/contrib/views/pig/src/main/resources/ui/pig-web/bin
@@ -0,0 +1 @@
+node_modules/.bin
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/ambari/blob/5eb22214/contrib/views/pig/src/main/resources/ui/pig-web/bower.json
----------------------------------------------------------------------
diff --git a/contrib/views/pig/src/main/resources/ui/pig-web/bower.json b/contrib/views/pig/src/main/resources/ui/pig-web/bower.json
new file mode 100644
index 0000000..44c5247
--- /dev/null
+++ b/contrib/views/pig/src/main/resources/ui/pig-web/bower.json
@@ -0,0 +1,22 @@
+{
+  "name": "your-app",
+  "version": "0.0.1",
+  "main": "public/app.js",
+  "dependencies": {
+    "ember": "1.4.0",
+    "ember-data": "1.0.0-beta.5",
+    "handlebars": "~1.3.0",
+    "bootstrap": "3.0.x",
+    "codemirror": ">=3.2",
+    "moment": "~2.5.1",
+    "ember-i18n": "~1.6.0"
+  },
+  "overrides": {
+    "cldr":{
+      "main":"plurals.js"
+    },
+    "ember-i18n":{
+      "scripts": []
+    }
+  }
+}

http://git-wip-us.apache.org/repos/asf/ambari/blob/5eb22214/contrib/views/pig/src/main/resources/ui/pig-web/config.coffee
----------------------------------------------------------------------
diff --git a/contrib/views/pig/src/main/resources/ui/pig-web/config.coffee b/contrib/views/pig/src/main/resources/ui/pig-web/config.coffee
new file mode 100644
index 0000000..867a9ee
--- /dev/null
+++ b/contrib/views/pig/src/main/resources/ui/pig-web/config.coffee
@@ -0,0 +1,51 @@
+#  Licensed to the Apache Software Foundation (ASF) under one
+#  or more contributor license agreements.  See the NOTICE file
+#  distributed with this work for additional information
+#  regarding copyright ownership.  The ASF licenses this file
+#  to you under the Apache License, Version 2.0 (the
+#  "License"); you may not use this file except in compliance
+#  with the License.  You may obtain a copy of the License at
+#  
+#      http://www.apache.org/licenses/LICENSE-2.0
+#   
+#   Unless required by applicable law or agreed to in writing, software
+#   distributed under the License is distributed on an "AS IS" BASIS,
+#   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+#   See the License for the specific language governing permissions and
+#   limitations under the License.
+
+exports.config = 
+
+  files: 
+    javascripts: 
+      defaultExtension: 'js'
+      joinTo: 
+        'static/javascripts/app.js': /^app/
+        'static/javascripts/vendor.js': /^bower_components|vendor/
+
+    stylesheets:
+      defaultExtension: 'css'
+      joinTo: 'static/stylesheets/app.css'
+
+    templates:
+      precompile: true
+      root: 'templates'
+      defaultExtension: 'hbs'
+      joinTo: 'static/javascripts/app.js' : /^app/
+      paths:
+        jquery: 'bower_components/jquery/jquery.js'
+        handlebars: 'bower_components/handlebars/handlebars.js'
+        ember: 'bower_components/ember/ember.js'
+
+  modules:
+    addSourceURLs: true
+
+
+  paths:
+    public: '/usr/lib/ambari-server/web/pig'
+
+  overrides:
+    production:
+        paths:
+          public: 'public'
+

http://git-wip-us.apache.org/repos/asf/ambari/blob/5eb22214/contrib/views/pig/src/main/resources/ui/pig-web/generators/collection/collection.js.hbs
----------------------------------------------------------------------
diff --git a/contrib/views/pig/src/main/resources/ui/pig-web/generators/collection/collection.js.hbs b/contrib/views/pig/src/main/resources/ui/pig-web/generators/collection/collection.js.hbs
new file mode 100644
index 0000000..04a95a9
--- /dev/null
+++ b/contrib/views/pig/src/main/resources/ui/pig-web/generators/collection/collection.js.hbs
@@ -0,0 +1,23 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+var App = require('app');
+
+App.{{#camelize}}{{pluralName}}{{/camelize}}Controller = Em.ArrayController.extend({
+    content: [] 
+});

http://git-wip-us.apache.org/repos/asf/ambari/blob/5eb22214/contrib/views/pig/src/main/resources/ui/pig-web/generators/collection/generator.json
----------------------------------------------------------------------
diff --git a/contrib/views/pig/src/main/resources/ui/pig-web/generators/collection/generator.json b/contrib/views/pig/src/main/resources/ui/pig-web/generators/collection/generator.json
new file mode 100644
index 0000000..9c40630
--- /dev/null
+++ b/contrib/views/pig/src/main/resources/ui/pig-web/generators/collection/generator.json
@@ -0,0 +1,9 @@
+{
+  "files": [
+    {
+      "from": "collection.js.hbs",
+      "to": "app/controllers/{{pluralName}}.js"
+    }
+  ],
+  "dependencies": []
+}

http://git-wip-us.apache.org/repos/asf/ambari/blob/5eb22214/contrib/views/pig/src/main/resources/ui/pig-web/generators/controller/controller.js.hbs
----------------------------------------------------------------------
diff --git a/contrib/views/pig/src/main/resources/ui/pig-web/generators/controller/controller.js.hbs b/contrib/views/pig/src/main/resources/ui/pig-web/generators/controller/controller.js.hbs
new file mode 100644
index 0000000..66c11bb
--- /dev/null
+++ b/contrib/views/pig/src/main/resources/ui/pig-web/generators/controller/controller.js.hbs
@@ -0,0 +1,23 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+var App = require('app');
+
+App.{{#camelize}}{{name}}{{/camelize}}Controller = Em.ObjectController.extend({
+    content: null
+});

http://git-wip-us.apache.org/repos/asf/ambari/blob/5eb22214/contrib/views/pig/src/main/resources/ui/pig-web/generators/controller/generator.json
----------------------------------------------------------------------
diff --git a/contrib/views/pig/src/main/resources/ui/pig-web/generators/controller/generator.json b/contrib/views/pig/src/main/resources/ui/pig-web/generators/controller/generator.json
new file mode 100644
index 0000000..f9ddf55
--- /dev/null
+++ b/contrib/views/pig/src/main/resources/ui/pig-web/generators/controller/generator.json
@@ -0,0 +1,9 @@
+{
+  "files": [
+    {
+      "from": "controller.js.hbs",
+      "to": "app/controllers/{{name}}.js"
+    }
+  ],
+  "dependencies": []
+}

http://git-wip-us.apache.org/repos/asf/ambari/blob/5eb22214/contrib/views/pig/src/main/resources/ui/pig-web/generators/model/generator.json
----------------------------------------------------------------------
diff --git a/contrib/views/pig/src/main/resources/ui/pig-web/generators/model/generator.json b/contrib/views/pig/src/main/resources/ui/pig-web/generators/model/generator.json
new file mode 100644
index 0000000..f41ac7e
--- /dev/null
+++ b/contrib/views/pig/src/main/resources/ui/pig-web/generators/model/generator.json
@@ -0,0 +1,9 @@
+{
+  "files": [
+    {
+      "from": "model.js.hbs",
+      "to": "app/models/{{name}}.js"
+    }
+  ],
+  "dependencies": []
+}

http://git-wip-us.apache.org/repos/asf/ambari/blob/5eb22214/contrib/views/pig/src/main/resources/ui/pig-web/generators/model/model.js.hbs
----------------------------------------------------------------------
diff --git a/contrib/views/pig/src/main/resources/ui/pig-web/generators/model/model.js.hbs b/contrib/views/pig/src/main/resources/ui/pig-web/generators/model/model.js.hbs
new file mode 100644
index 0000000..d5f5ece
--- /dev/null
+++ b/contrib/views/pig/src/main/resources/ui/pig-web/generators/model/model.js.hbs
@@ -0,0 +1,23 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+var App = require('app');
+
+App.{{#camelize}}{{name}}{{/camelize}} = DS.Model.extend({
+    
+});

http://git-wip-us.apache.org/repos/asf/ambari/blob/5eb22214/contrib/views/pig/src/main/resources/ui/pig-web/generators/route/generator.json
----------------------------------------------------------------------
diff --git a/contrib/views/pig/src/main/resources/ui/pig-web/generators/route/generator.json b/contrib/views/pig/src/main/resources/ui/pig-web/generators/route/generator.json
new file mode 100644
index 0000000..c9123ec
--- /dev/null
+++ b/contrib/views/pig/src/main/resources/ui/pig-web/generators/route/generator.json
@@ -0,0 +1,9 @@
+{
+  "files": [
+    {
+      "from": "route.js.hbs",
+      "to": "app/routes/{{name}}.js"
+    }
+  ],
+  "dependencies": []
+}

http://git-wip-us.apache.org/repos/asf/ambari/blob/5eb22214/contrib/views/pig/src/main/resources/ui/pig-web/generators/route/route.js.hbs
----------------------------------------------------------------------
diff --git a/contrib/views/pig/src/main/resources/ui/pig-web/generators/route/route.js.hbs b/contrib/views/pig/src/main/resources/ui/pig-web/generators/route/route.js.hbs
new file mode 100644
index 0000000..ec5216a
--- /dev/null
+++ b/contrib/views/pig/src/main/resources/ui/pig-web/generators/route/route.js.hbs
@@ -0,0 +1,25 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+var App = require('app');
+
+App.{{#camelize}}{{name}}{{/camelize}}Route = Em.Route.extend({
+    model: function (controller) {
+
+    }
+});

http://git-wip-us.apache.org/repos/asf/ambari/blob/5eb22214/contrib/views/pig/src/main/resources/ui/pig-web/generators/template/generator.json
----------------------------------------------------------------------
diff --git a/contrib/views/pig/src/main/resources/ui/pig-web/generators/template/generator.json b/contrib/views/pig/src/main/resources/ui/pig-web/generators/template/generator.json
new file mode 100644
index 0000000..dc51724
--- /dev/null
+++ b/contrib/views/pig/src/main/resources/ui/pig-web/generators/template/generator.json
@@ -0,0 +1,9 @@
+{
+  "files": [
+    {
+      "from": "template.hbs.hbs",
+      "to": "app/templates/{{name}}.hbs"
+    }
+  ],
+  "dependencies": []
+}

http://git-wip-us.apache.org/repos/asf/ambari/blob/5eb22214/contrib/views/pig/src/main/resources/ui/pig-web/generators/template/template.hbs.hbs
----------------------------------------------------------------------
diff --git a/contrib/views/pig/src/main/resources/ui/pig-web/generators/template/template.hbs.hbs b/contrib/views/pig/src/main/resources/ui/pig-web/generators/template/template.hbs.hbs
new file mode 100644
index 0000000..0efb5b2
--- /dev/null
+++ b/contrib/views/pig/src/main/resources/ui/pig-web/generators/template/template.hbs.hbs
@@ -0,0 +1,18 @@
+{{!
+   Licensed to the Apache Software Foundation (ASF) under one
+   or more contributor license agreements.  See the NOTICE file
+   distributed with this work for additional information
+   regarding copyright ownership.  The ASF licenses this file
+   to you under the Apache License, Version 2.0 (the
+   "License"); you may not use this file except in compliance
+   with the License.  You may obtain a copy of the License at
+  
+       http://www.apache.org/licenses/LICENSE-2.0
+  
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.
+}}
+

http://git-wip-us.apache.org/repos/asf/ambari/blob/5eb22214/contrib/views/pig/src/main/resources/ui/pig-web/generators/view/generator.json
----------------------------------------------------------------------
diff --git a/contrib/views/pig/src/main/resources/ui/pig-web/generators/view/generator.json b/contrib/views/pig/src/main/resources/ui/pig-web/generators/view/generator.json
new file mode 100644
index 0000000..7328337
--- /dev/null
+++ b/contrib/views/pig/src/main/resources/ui/pig-web/generators/view/generator.json
@@ -0,0 +1,9 @@
+{
+  "files": [
+    {
+      "from": "view.js.hbs",
+      "to": "app/views/{{name}}.js"
+    }
+  ],
+  "dependencies": []
+}

http://git-wip-us.apache.org/repos/asf/ambari/blob/5eb22214/contrib/views/pig/src/main/resources/ui/pig-web/generators/view/view.js.hbs
----------------------------------------------------------------------
diff --git a/contrib/views/pig/src/main/resources/ui/pig-web/generators/view/view.js.hbs b/contrib/views/pig/src/main/resources/ui/pig-web/generators/view/view.js.hbs
new file mode 100644
index 0000000..7e35717
--- /dev/null
+++ b/contrib/views/pig/src/main/resources/ui/pig-web/generators/view/view.js.hbs
@@ -0,0 +1,23 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+var App = require('app');
+
+App.{{#camelize}}{{name}}{{/camelize}}View = Em.View.extend({
+    templateName: '{{name}}'
+});

http://git-wip-us.apache.org/repos/asf/ambari/blob/5eb22214/contrib/views/pig/src/main/resources/ui/pig-web/package.json
----------------------------------------------------------------------
diff --git a/contrib/views/pig/src/main/resources/ui/pig-web/package.json b/contrib/views/pig/src/main/resources/ui/pig-web/package.json
new file mode 100644
index 0000000..abedb74
--- /dev/null
+++ b/contrib/views/pig/src/main/resources/ui/pig-web/package.json
@@ -0,0 +1,22 @@
+{
+  "name": "pig-ui",
+  "version": "0.0.1",
+  "engines": {
+    "node": "~0.6.10 || 0.8 || 0.9"
+  },
+  "scripts": {
+    "start": "brunch watch --server",
+    "preinstall": "chmod +x node/npm/bin/node-gyp-bin/node-gyp",
+    "postinstall" : "bash node/with_new_path.sh node node_modules/.bin/bower --allow-root install"
+  },
+  "dependencies": {
+    "brunch": ">= 1.7.1",
+    "javascript-brunch": ">= 1.0 < 1.8",
+    "css-brunch": ">= 1.0 < 1.8",
+    "uglify-js-brunch": ">= 1.0 < 1.8",
+    "bower": ">= 1.2.0",
+    "ember-precompiler-brunch": ">= 1.5.0",
+    "less-brunch": "~1.7.1",
+    "scaffolt": "^0.4.3"
+  }
+}

http://git-wip-us.apache.org/repos/asf/ambari/blob/5eb22214/contrib/views/pig/src/main/resources/ui/pig-web/test/spec.coffee
----------------------------------------------------------------------
diff --git a/contrib/views/pig/src/main/resources/ui/pig-web/test/spec.coffee b/contrib/views/pig/src/main/resources/ui/pig-web/test/spec.coffee
new file mode 100644
index 0000000..ecf0374
--- /dev/null
+++ b/contrib/views/pig/src/main/resources/ui/pig-web/test/spec.coffee
@@ -0,0 +1,17 @@
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements.  See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership.  The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License.  You may obtain a copy of the License at
+#
+#     http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+# Write your [mocha](http://visionmedia.github.com/mocha/) specs here.

http://git-wip-us.apache.org/repos/asf/ambari/blob/5eb22214/contrib/views/pig/src/main/resources/ui/pig-web/vendor/emacs.js
----------------------------------------------------------------------
diff --git a/contrib/views/pig/src/main/resources/ui/pig-web/vendor/emacs.js b/contrib/views/pig/src/main/resources/ui/pig-web/vendor/emacs.js
new file mode 100644
index 0000000..23666f2
--- /dev/null
+++ b/contrib/views/pig/src/main/resources/ui/pig-web/vendor/emacs.js
@@ -0,0 +1,50 @@
+(function() {
+  String.prototype.regexIndexOf = function(regex, startpos) {
+    var indexOf = this.substring(startpos || 0).search(regex);
+    return (indexOf >= 0) ? (indexOf + (startpos || 0)) : indexOf;
+  }
+
+  function regFindPosition(curLine){
+    var pos= curLine.regexIndexOf(/\%\w*\%/);
+    var posArr=[];
+    while(pos > -1) {
+      posArr.push(pos);
+      pos = curLine.regexIndexOf(/\%\w*\%/,pos+1);
+    }
+    return posArr;
+  }
+
+  CodeMirror.keyMap.emacs = {
+    fallthrough: ["basic", "default"],
+    "Tab": function(cm) {
+      var cursor = cm.getCursor();
+      var curLine = cm.getLine(cursor.line);
+      var vArr = regFindPosition(curLine);
+      var paramRanges = [];
+
+      for (var i = 0; i < vArr.length; i++) {
+        closeparam = curLine.regexIndexOf(/\%/, vArr[i]+1);
+        paramRanges.push({s:vArr[i],e:closeparam});
+      };
+
+      if(vArr.length>1){
+        if (cursor.ch < paramRanges[0].s) {
+          CodeMirror.commands.defaultTab(cm);
+        } else {
+          var thisrange, nextrange;
+          for (var i = 0; i < paramRanges.length; i++) {
+            thisrange = paramRanges[i];
+            nextrange = paramRanges[i+1] || paramRanges[0];
+            if (cursor.ch > thisrange.s && (cursor.ch < nextrange.s || nextrange.s < thisrange.s)){
+              cm.setSelection({line:cursor.line, ch:nextrange.s},{line:cursor.line, ch:nextrange.e+1});
+            } else if (cursor.ch == thisrange.s){
+              cm.setSelection({line:cursor.line, ch:thisrange.s},{line:cursor.line, ch:thisrange.e+1});
+            }
+          }
+        }
+      } else {
+        CodeMirror.commands.defaultTab(cm);
+      }
+    }
+  };
+})();

http://git-wip-us.apache.org/repos/asf/ambari/blob/5eb22214/contrib/views/pig/src/main/resources/view.xml
----------------------------------------------------------------------
diff --git a/contrib/views/pig/src/main/resources/view.xml b/contrib/views/pig/src/main/resources/view.xml
new file mode 100644
index 0000000..257f421
--- /dev/null
+++ b/contrib/views/pig/src/main/resources/view.xml
@@ -0,0 +1,140 @@
+<!--
+   Licensed to the Apache Software Foundation (ASF) under one or more
+   contributor license agreements.  See the NOTICE file distributed with
+   this work for additional information regarding copyright ownership.
+   The ASF licenses this file to You under the Apache License, Version 2.0
+   (the "License"); you may not use this file except in compliance with
+   the License.  You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.
+-->
+<view>
+    <name>PIG</name>
+    <label>Pig</label>
+    <version>1.0.0</version>
+
+    <!-- HDFS parameters -->
+    <parameter>
+        <name>dataworker.defaultFs</name>
+        <description>FileSystem URI</description>
+        <required>true</required>
+    </parameter>
+
+    <parameter>
+        <name>dataworker.hdfs_user</name>
+        <description>HDFS user.name and doAs</description>
+        <required>false</required>
+    </parameter>
+
+    <parameter>
+        <name>dataworker.use_current_user</name>
+        <description>If true, get user from Ambari auth</description>
+        <required>true</required>
+    </parameter>
+
+    <parameter>
+        <name>dataworker.userScriptsPath</name>
+        <description>Directory to store scripts</description>
+        <required>true</required>
+    </parameter>
+    <parameter>
+        <name>dataworker.pigJobsPath</name>
+        <description>Directory to store jobs (for templeton status dir)</description>
+        <required>true</required>
+    </parameter>
+
+    <!-- Pig parameters -->
+
+    <parameter>
+        <name>dataworker.storagePath</name>
+        <description>Persistent storage path</description>
+        <required>false</required>
+    </parameter>
+
+    <parameter>
+        <name>dataworker.templeton_url</name>
+        <description>Templeton url</description>
+        <required>true</required>
+    </parameter>
+
+    <parameter>
+        <name>dataworker.templeton_user</name>
+        <description>Templeton user.name and doAs</description>
+        <required>true</required>
+    </parameter>
+
+    <resource>
+        <name>script</name>
+        <plural-name>scripts</plural-name>
+        <id-property>id</id-property>
+        <resource-class>org.apache.ambari.view.pig.resources.scripts.models.PigScript</resource-class>
+        <provider-class>org.apache.ambari.view.pig.resources.scripts.ScriptResourceProvider</provider-class>
+        <service-class>org.apache.ambari.view.pig.resources.scripts.ScriptService</service-class>
+    </resource>
+
+    <resource>
+        <name>job</name>
+        <plural-name>jobs</plural-name>
+        <id-property>id</id-property>
+        <resource-class>org.apache.ambari.view.pig.resources.jobs.models.PigJob</resource-class>
+        <provider-class>org.apache.ambari.view.pig.resources.jobs.JobResourceProvider</provider-class>
+        <service-class>org.apache.ambari.view.pig.resources.jobs.JobService</service-class>
+    </resource>
+
+    <resource>
+        <name>udf</name>
+        <plural-name>udfs</plural-name>
+        <id-property>id</id-property>
+        <resource-class>org.apache.ambari.view.pig.resources.udf.models.UDF</resource-class>
+        <provider-class>org.apache.ambari.view.pig.resources.udf.UDFResourceProvider</provider-class>
+        <service-class>org.apache.ambari.view.pig.resources.udf.UDFService</service-class>
+    </resource>
+
+    <resource>
+        <name>file</name>
+        <service-class>org.apache.ambari.view.pig.resources.files.FileService</service-class>
+    </resource>
+
+    <resource>
+        <name>pig</name>
+        <service-class>org.apache.ambari.view.pig.PigServiceRouter</service-class>
+    </resource>
+
+    <instance>
+        <name>PIG_1</name>
+        <!--<property>-->
+            <!--<key>dataworker.storagePath</key>-->
+            <!--<value>/var/lib/ambari-server/pig-view.dat</value>-->
+        <!--</property>-->
+        <property>
+            <key>dataworker.templeton_url</key>
+            <value>http://sandbox.hortonworks.com:50111/templeton/v1</value>
+        </property>
+        <property>
+            <key>dataworker.templeton_user</key>
+            <value>hue</value>
+        </property>
+
+        <property>
+            <key>dataworker.userScriptsPath</key>
+            <value>/tmp/.pigscripts</value>
+        </property>
+        <property>
+            <key>dataworker.pigJobsPath</key>
+            <value>/tmp/.pigjobs</value>
+        </property>
+
+        <property>
+            <key>dataworker.defaultFs</key>
+            <!-- WebHDFS requires 50070 and 50075 ports to be opened -->
+            <value>webhdfs://sandbox.hortonworks.com:50070</value>
+        </property>
+    </instance>
+
+</view>

http://git-wip-us.apache.org/repos/asf/ambari/blob/5eb22214/contrib/views/pig/src/test/java/org/apache/ambari/view/pig/BasePigTest.java
----------------------------------------------------------------------
diff --git a/contrib/views/pig/src/test/java/org/apache/ambari/view/pig/BasePigTest.java b/contrib/views/pig/src/test/java/org/apache/ambari/view/pig/BasePigTest.java
new file mode 100644
index 0000000..7a237d7
--- /dev/null
+++ b/contrib/views/pig/src/test/java/org/apache/ambari/view/pig/BasePigTest.java
@@ -0,0 +1,96 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.ambari.view.pig;
+
+import com.google.inject.AbstractModule;
+import com.google.inject.Guice;
+import com.google.inject.Injector;
+import org.apache.ambari.view.ViewContext;
+import org.apache.ambari.view.ViewResourceHandler;
+import org.apache.hadoop.fs.FileUtil;
+import org.junit.*;
+
+import java.io.File;
+import java.util.HashMap;
+import java.util.Map;
+
+import static org.easymock.EasyMock.*;
+
+public abstract class BasePigTest {
+    protected ViewResourceHandler handler;
+    protected ViewContext context;
+    protected static File pigStorageFile;
+    protected static File baseDir;
+
+    protected static String DATA_DIRECTORY = "./target/PigTest";
+
+    @BeforeClass
+    public static void startUp() throws Exception {
+        File baseDir = new File(DATA_DIRECTORY)
+                .getAbsoluteFile();
+        FileUtil.fullyDelete(baseDir);
+    }
+
+    @Before
+    public void setUp() throws Exception {
+        handler = createNiceMock(ViewResourceHandler.class);
+        context = createNiceMock(ViewContext.class);
+
+        Map<String, String> properties = new HashMap<String, String>();
+        baseDir = new File(DATA_DIRECTORY)
+                .getAbsoluteFile();
+        pigStorageFile = new File("./target/BasePigTest/storage.dat")
+                .getAbsoluteFile();
+
+        properties.put("dataworker.storagePath", pigStorageFile.toString());
+        properties.put("dataworker.templeton_url", "localhost:50111/templeton/v1");
+        properties.put("dataworker.templeton_user", "admin");
+        properties.put("dataworker.userScriptsPath", "/tmp/.pigscripts");
+        properties.put("dataworker.pigJobsPath", "/tmp/.pigjobs");
+
+        setupProperties(properties, baseDir);
+
+        expect(context.getProperties()).andReturn(properties).anyTimes();
+        expect(context.getUsername()).andReturn("ambari-qa").anyTimes();
+
+        replay(handler, context);
+    }
+
+    protected void setupProperties(Map<String, String> properties, File baseDir) throws Exception {
+
+    }
+
+    @After
+    public void tearDown() throws Exception {
+
+    }
+
+    protected static <T> T getService(Class<T> clazz,
+                                    final ViewResourceHandler viewResourceHandler,
+                                    final ViewContext viewInstanceContext) {
+        Injector viewInstanceInjector = Guice.createInjector(new AbstractModule() {
+            @Override
+            protected void configure() {
+                bind(ViewResourceHandler.class).toInstance(viewResourceHandler);
+                bind(ViewContext.class).toInstance(viewInstanceContext);
+            }
+        });
+        return viewInstanceInjector.getInstance(clazz);
+    }
+}

http://git-wip-us.apache.org/repos/asf/ambari/blob/5eb22214/contrib/views/pig/src/test/java/org/apache/ambari/view/pig/HDFSTest.java
----------------------------------------------------------------------
diff --git a/contrib/views/pig/src/test/java/org/apache/ambari/view/pig/HDFSTest.java b/contrib/views/pig/src/test/java/org/apache/ambari/view/pig/HDFSTest.java
new file mode 100644
index 0000000..214c6ef
--- /dev/null
+++ b/contrib/views/pig/src/test/java/org/apache/ambari/view/pig/HDFSTest.java
@@ -0,0 +1,60 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.ambari.view.pig;
+
+import org.apache.hadoop.conf.Configuration;
+import org.apache.hadoop.fs.FileUtil;
+import org.apache.hadoop.hdfs.MiniDFSCluster;
+import org.junit.AfterClass;
+import org.junit.BeforeClass;
+
+import java.io.File;
+import java.util.Map;
+
+public abstract class HDFSTest extends BasePigTest {
+    protected static MiniDFSCluster hdfsCluster;
+    protected static String hdfsURI;
+
+    @BeforeClass
+    public static void startUp() throws Exception {
+        BasePigTest.startUp(); // super
+        File hdfsDir = new File("./target/PigTest/hdfs/")
+                .getAbsoluteFile();
+        FileUtil.fullyDelete(hdfsDir);
+
+        Configuration conf = new Configuration();
+        conf.set(MiniDFSCluster.HDFS_MINIDFS_BASEDIR, hdfsDir.getAbsolutePath());
+
+        MiniDFSCluster.Builder builder = new MiniDFSCluster.Builder(conf);
+        hdfsCluster = builder.build();
+        hdfsURI = hdfsCluster.getURI().toString();
+    }
+
+    @AfterClass
+    public static void shutDown() throws Exception {
+        hdfsCluster.shutdown();
+        hdfsCluster = null;
+    }
+
+    @Override
+    protected void setupProperties(Map<String, String> properties, File baseDir) throws Exception {
+        super.setupProperties(properties, baseDir);
+        properties.put("dataworker.defaultFs", hdfsURI);
+    }
+}

http://git-wip-us.apache.org/repos/asf/ambari/blob/5eb22214/contrib/views/pig/src/test/java/org/apache/ambari/view/pig/test/FileTest.java
----------------------------------------------------------------------
diff --git a/contrib/views/pig/src/test/java/org/apache/ambari/view/pig/test/FileTest.java b/contrib/views/pig/src/test/java/org/apache/ambari/view/pig/test/FileTest.java
new file mode 100644
index 0000000..1e78ee6
--- /dev/null
+++ b/contrib/views/pig/src/test/java/org/apache/ambari/view/pig/test/FileTest.java
@@ -0,0 +1,203 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.ambari.view.pig.test;
+
+import org.apache.ambari.view.pig.HDFSTest;
+import org.apache.ambari.view.pig.resources.files.FileResource;
+import org.apache.ambari.view.pig.resources.files.FileService;
+import org.apache.ambari.view.pig.utils.FilePaginator;
+import org.json.simple.JSONObject;
+import org.junit.*;
+
+import javax.servlet.http.HttpServletResponse;
+import javax.ws.rs.core.Response;
+import javax.ws.rs.core.UriBuilder;
+import javax.ws.rs.core.UriInfo;
+import java.io.IOException;
+import java.net.URI;
+import java.util.UUID;
+
+import static org.easymock.EasyMock.*;
+
+public class FileTest extends HDFSTest {
+    private final static int PAGINATOR_PAGE_SIZE = 4;
+    private FileService fileService;
+
+    @Override
+    @Before
+    public void setUp() throws Exception {
+        super.setUp();
+        fileService = getService(FileService.class, handler, context);
+        FilePaginator.setPageSize(PAGINATOR_PAGE_SIZE);
+    }
+
+    @BeforeClass
+    public static void startUp() throws Exception {
+        HDFSTest.startUp(); // super
+    }
+
+    @AfterClass
+    public static void shutDown() throws Exception {
+        HDFSTest.shutDown(); // super
+        FileService.setHdfsApi(null); //cleanup API connection
+    }
+
+    private Response doCreateFile() throws IOException, InterruptedException {
+        replay(handler, context);
+        return doCreateFile("luke", "i'm your father");
+    }
+
+    private Response doCreateFile(String name, String content) throws IOException, InterruptedException {
+        return doCreateFile(name, content, "/tmp/");
+    }
+
+    private Response doCreateFile(String name, String content, String filePath) throws IOException, InterruptedException {
+        FileService.FileResourceRequest request = new FileService.FileResourceRequest();
+        request.file = new FileResource();
+        request.file.filePath = filePath + name;
+        request.file.fileContent = content;
+
+        HttpServletResponse resp_obj = createNiceMock(HttpServletResponse.class);
+        resp_obj.setHeader(eq("Location"), anyString());
+
+        UriInfo uriInfo = createNiceMock(UriInfo.class);
+        URI uri = UriBuilder.fromUri("http://host/a/b").build();
+        expect(uriInfo.getAbsolutePath()).andReturn(uri);
+
+        replay(resp_obj, uriInfo);
+        return fileService.createFile(request, resp_obj, uriInfo);
+    }
+
+    @Test
+    public void testCreateFile() throws IOException, InterruptedException {
+        String name = UUID.randomUUID().toString().replaceAll("-", "");
+        Response response = doCreateFile(name, "12323");
+        Assert.assertEquals(204, response.getStatus());
+
+        String name2 = UUID.randomUUID().toString().replaceAll("-", "");
+        Response response2 = doCreateFile(name2, "12323");
+        Assert.assertEquals(204, response2.getStatus());
+    }
+
+    @Test
+    public void testCreateFilePathNotExists() throws IOException, InterruptedException {
+        Response response = doCreateFile("Luke", null, "/non/existent/path/");
+        Assert.assertEquals(204, response.getStatus());  // path created automatically
+
+        Response response2 = doCreateFile("Leia", null, "/tmp/");
+        Assert.assertEquals(204, response2.getStatus());
+
+        Response response3 = doCreateFile("Leia", null, "/tmp/"); // file already exists
+        Assert.assertEquals(400, response3.getStatus());
+    }
+
+    @Test
+    public void testUpdateFileContent() throws Exception {
+        String name = UUID.randomUUID().toString().replaceAll("-", "");
+        String filePath = "/tmp/" + name;
+
+        Response createdFile = doCreateFile(name, "some content");
+        FileService.FileResourceRequest request = new FileService.FileResourceRequest();
+        request.file = new FileResource();
+        request.file.filePath = filePath;
+        request.file.fileContent = "1234567890";  // 10 bytes, 3*(4b page)
+
+        Response response = fileService.updateFile(request, filePath);
+        Assert.assertEquals(204, response.getStatus());
+
+        Response response2 = fileService.getFile(filePath, 0L);
+        Assert.assertEquals(200, response2.getStatus());
+
+        JSONObject obj = ((JSONObject) response2.getEntity());
+        Assert.assertTrue(obj.containsKey("file"));
+        Assert.assertEquals("1234", ((FileResource) obj.get("file")).fileContent);
+    }
+
+    @Test
+    public void testPagination() throws Exception {
+        String name = UUID.randomUUID().toString().replaceAll("-", "");
+        String filePath = "/tmp/" + name;
+
+        doCreateFile(name, "1234567890");
+
+        Response response = fileService.getFile(filePath, 0L);
+        Assert.assertEquals(200, response.getStatus());
+
+        JSONObject obj = ((JSONObject) response.getEntity());
+        Assert.assertTrue(obj.containsKey("file"));
+        Assert.assertEquals("1234", ((FileResource) obj.get("file")).fileContent);
+        Assert.assertEquals(3, ((FileResource) obj.get("file")).pageCount);
+        Assert.assertEquals(0, ((FileResource) obj.get("file")).page);
+        Assert.assertTrue(((FileResource) obj.get("file")).hasNext);
+        Assert.assertEquals(filePath, ((FileResource) obj.get("file")).filePath);
+
+        response = fileService.getFile(filePath, 1L);
+        Assert.assertEquals(200, response.getStatus());
+
+        obj = ((JSONObject) response.getEntity());
+        Assert.assertEquals("5678", ((FileResource) obj.get("file")).fileContent);
+        Assert.assertEquals(1, ((FileResource) obj.get("file")).page);
+        Assert.assertTrue(((FileResource) obj.get("file")).hasNext);
+
+        response = fileService.getFile(filePath, 2L);
+        Assert.assertEquals(200, response.getStatus());
+
+        obj = ((JSONObject) response.getEntity());
+        Assert.assertEquals("90", ((FileResource) obj.get("file")).fileContent);
+        Assert.assertEquals(2, ((FileResource) obj.get("file")).page);
+        Assert.assertFalse(((FileResource) obj.get("file")).hasNext);
+
+        response = fileService.getFile(filePath, 3L);
+        Assert.assertEquals(400, response.getStatus()); //page not found
+    }
+
+    @Test
+    public void testZeroLengthFile() throws Exception {
+        String name = UUID.randomUUID().toString().replaceAll("-", "");
+        String filePath = "/tmp/" + name;
+
+        doCreateFile(name, "");
+
+        Response response = fileService.getFile(filePath, 0L);
+        Assert.assertEquals(200, response.getStatus());
+        JSONObject obj = ((JSONObject) response.getEntity());
+        Assert.assertEquals("", ((FileResource) obj.get("file")).fileContent);
+        Assert.assertEquals(0, ((FileResource) obj.get("file")).page);
+        Assert.assertFalse(((FileResource) obj.get("file")).hasNext);
+    }
+
+    @Test
+    public void testFileNotFound() throws IOException, InterruptedException {
+        Response response1 = fileService.getFile("/tmp/notExistentFile", 2L);
+        Assert.assertEquals(404, response1.getStatus());
+    }
+
+    @Test
+    public void testDeleteFile() throws IOException, InterruptedException {
+        String name = UUID.randomUUID().toString().replaceAll("-", "");
+        String filePath = "/tmp/" + name;
+        Response createdFile = doCreateFile(name, "some content");
+
+        Response response = fileService.deleteFile(filePath);
+        Assert.assertEquals(204, response.getStatus());
+
+        Response response2 = fileService.getFile(filePath, 0L);
+        Assert.assertEquals(404, response2.getStatus());
+    }
+}


[5/7] AMBARI-5616 - Ambari Views: Pig view (Roman Rader via tbeerbower)

Posted by tb...@apache.org.
http://git-wip-us.apache.org/repos/asf/ambari/blob/5eb22214/contrib/views/pig/src/main/java/org/apache/ambari/view/pig/utils/HdfsApi.java
----------------------------------------------------------------------
diff --git a/contrib/views/pig/src/main/java/org/apache/ambari/view/pig/utils/HdfsApi.java b/contrib/views/pig/src/main/java/org/apache/ambari/view/pig/utils/HdfsApi.java
new file mode 100644
index 0000000..9068475
--- /dev/null
+++ b/contrib/views/pig/src/main/java/org/apache/ambari/view/pig/utils/HdfsApi.java
@@ -0,0 +1,189 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.ambari.view.pig.utils;
+
+import org.apache.hadoop.conf.Configuration;
+import org.apache.hadoop.fs.*;
+import org.apache.hadoop.fs.permission.FsPermission;
+
+import org.apache.hadoop.hdfs.DistributedFileSystem;
+import org.apache.hadoop.hdfs.web.WebHdfsFileSystem;
+
+import java.io.FileNotFoundException;
+import java.io.IOException;
+import java.net.URI;
+import java.security.PrivilegedExceptionAction;
+import java.util.Map;
+
+import org.apache.hadoop.security.UserGroupInformation;
+import org.json.simple.JSONArray;
+
+import java.util.LinkedHashMap;
+
+public class HdfsApi {
+    private Configuration conf = new Configuration();
+
+    private FileSystem fs;
+    private UserGroupInformation ugi;
+
+    public HdfsApi(String defaultFs, String username) throws IOException,
+        InterruptedException {
+        Thread.currentThread().setContextClassLoader(null);
+        conf.set("fs.hdfs.impl", DistributedFileSystem.class.getName());
+        conf.set("fs.webhdfs.impl", WebHdfsFileSystem.class.getName());
+        conf.set("fs.file.impl", "org.apache.hadoop.fs.LocalFileSystem");
+        fs = FileSystem.get(URI.create(defaultFs), conf);
+        ugi = UserGroupInformation.createProxyUser(username,
+            UserGroupInformation.getLoginUser());
+    }
+
+    public FileStatus[] listdir(final String path) throws FileNotFoundException,
+        IOException, InterruptedException {
+        return ugi.doAs(new PrivilegedExceptionAction<FileStatus[]>() {
+            public FileStatus[] run() throws FileNotFoundException, Exception {
+                return fs.listStatus(new Path(path));
+            }
+        });
+    }
+
+    public FileStatus getFileStatus(final String path) throws IOException,
+        FileNotFoundException, InterruptedException {
+        return ugi.doAs(new PrivilegedExceptionAction<FileStatus>() {
+            public FileStatus run() throws FileNotFoundException, IOException {
+                return fs.getFileStatus(new Path(path));
+            }
+        });
+    }
+
+    public boolean mkdir(final String path) throws IOException,
+        InterruptedException {
+        return ugi.doAs(new PrivilegedExceptionAction<Boolean>() {
+            public Boolean run() throws Exception {
+                return fs.mkdirs(new Path(path));
+            }
+        });
+    }
+
+    public boolean rename(final String src, final String dst) throws IOException,
+        InterruptedException {
+        return ugi.doAs(new PrivilegedExceptionAction<Boolean>() {
+            public Boolean run() throws Exception {
+                return fs.rename(new Path(src), new Path(dst));
+            }
+        });
+    }
+
+    public boolean delete(final String path, final boolean recursive)
+        throws IOException, InterruptedException {
+        return ugi.doAs(new PrivilegedExceptionAction<Boolean>() {
+            public Boolean run() throws Exception {
+                return fs.delete(new Path(path), recursive);
+            }
+        });
+    }
+
+    public FSDataOutputStream create(final String path, final boolean overwrite)
+        throws IOException, InterruptedException {
+        return ugi.doAs(new PrivilegedExceptionAction<FSDataOutputStream>() {
+            public FSDataOutputStream run() throws Exception {
+                return fs.create(new Path(path), overwrite);
+            }
+        });
+    }
+
+    public FSDataInputStream open(final String path) throws IOException,
+        InterruptedException {
+        return ugi.doAs(new PrivilegedExceptionAction<FSDataInputStream>() {
+            public FSDataInputStream run() throws Exception {
+                return fs.open(new Path(path));
+            }
+        });
+    }
+
+    public boolean copy(final String src, final String dest) throws IOException,
+            InterruptedException {
+        return ugi.doAs(new PrivilegedExceptionAction<Boolean>() {
+            public Boolean run() throws Exception {
+                return FileUtil.copy(fs, new Path(src), fs, new Path(dest), false, conf);
+            }
+        });
+    }
+
+    /**
+     * Converts a Hadoop permission into a Unix permission symbolic representation
+     * (i.e. -rwxr--r--) or default if the permission is NULL.
+     *
+     * @param p
+     *          Hadoop permission.
+     * @return the Unix permission symbolic representation or default if the
+     *         permission is NULL.
+     */
+    private static String permissionToString(FsPermission p) {
+        return (p == null) ? "default" : "-" + p.getUserAction().SYMBOL
+            + p.getGroupAction().SYMBOL + p.getOtherAction().SYMBOL;
+    }
+
+    /**
+     * Converts a Hadoop <code>FileStatus</code> object into a JSON array object.
+     * It replaces the <code>SCHEME://HOST:PORT</code> of the path with the
+     * specified URL.
+     * <p/>
+     *
+     * @param status
+     *          Hadoop file status.
+     * @return The JSON representation of the file status.
+     */
+
+    public static Map<String, Object> fileStatusToJSON(FileStatus status) {
+        Map<String, Object> json = new LinkedHashMap<String, Object>();
+        json.put("path", status.getPath().toString());
+        json.put("isDirectory", status.isDirectory());
+        json.put("len", status.getLen());
+        json.put("owner", status.getOwner());
+        json.put("group", status.getGroup());
+        json.put("permission", permissionToString(status.getPermission()));
+        json.put("accessTime", status.getAccessTime());
+        json.put("modificationTime", status.getModificationTime());
+        json.put("blockSize", status.getBlockSize());
+        json.put("replication", status.getReplication());
+        return json;
+    }
+
+    /**
+     * Converts a Hadoop <code>FileStatus</code> array into a JSON array object.
+     * It replaces the <code>SCHEME://HOST:PORT</code> of the path with the
+     * specified URL.
+     * <p/>
+     *
+     * @param status
+     *          Hadoop file status array.
+     * @return The JSON representation of the file status array.
+     */
+    @SuppressWarnings("unchecked")
+    public static JSONArray fileStatusToJSON(FileStatus[] status) {
+        JSONArray json = new JSONArray();
+        if (status != null) {
+            for (FileStatus s : status) {
+                json.add(fileStatusToJSON(s));
+            }
+        }
+        return json;
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/ambari/blob/5eb22214/contrib/views/pig/src/main/resources/ui/pig-web/.gitignore
----------------------------------------------------------------------
diff --git a/contrib/views/pig/src/main/resources/ui/pig-web/.gitignore b/contrib/views/pig/src/main/resources/ui/pig-web/.gitignore
new file mode 100644
index 0000000..d6ed7c3
--- /dev/null
+++ b/contrib/views/pig/src/main/resources/ui/pig-web/.gitignore
@@ -0,0 +1,34 @@
+# Numerous always-ignore extensions
+*.diff
+*.err
+*.orig
+*.log
+*.rej
+*.swo
+*.swp
+*.vi
+*~
+*.sass-cache
+
+# OS or Editor folders
+.DS_Store
+.cache
+.project
+.settings
+.tmproj
+nbproject
+Thumbs.db
+
+# NPM packages folder.
+node_modules/
+
+bower_components/
+
+node/
+
+# Brunch folder for temporary files.
+tmp/
+
+public/
+
+_generators/
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/ambari/blob/5eb22214/contrib/views/pig/src/main/resources/ui/pig-web/README.md
----------------------------------------------------------------------
diff --git a/contrib/views/pig/src/main/resources/ui/pig-web/README.md b/contrib/views/pig/src/main/resources/ui/pig-web/README.md
new file mode 100644
index 0000000..db8b8bb
--- /dev/null
+++ b/contrib/views/pig/src/main/resources/ui/pig-web/README.md
@@ -0,0 +1,15 @@
+<!---
+Licensed to the Apache Software Foundation (ASF) under one or more
+contributor license agreements.  See the NOTICE file distributed with
+this work for additional information regarding copyright ownership.
+The ASF licenses this file to You under the Apache License, Version 2.0
+(the "License"); you may not use this file except in compliance with
+the License.  You may obtain a copy of the License at [http://www.apache.org/licenses/LICENSE-2.0](http://www.apache.org/licenses/LICENSE-2.0)
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+-->
+

http://git-wip-us.apache.org/repos/asf/ambari/blob/5eb22214/contrib/views/pig/src/main/resources/ui/pig-web/app/app.js
----------------------------------------------------------------------
diff --git a/contrib/views/pig/src/main/resources/ui/pig-web/app/app.js b/contrib/views/pig/src/main/resources/ui/pig-web/app/app.js
new file mode 100644
index 0000000..5d73a3f
--- /dev/null
+++ b/contrib/views/pig/src/main/resources/ui/pig-web/app/app.js
@@ -0,0 +1,23 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+// Application bootstrapper
+module.exports = Em.Application.create({
+  //LOG_TRANSITIONS: true, 
+  //LOG_TRANSITIONS_INTERNAL: true
+});

http://git-wip-us.apache.org/repos/asf/ambari/blob/5eb22214/contrib/views/pig/src/main/resources/ui/pig-web/app/assets/fonts/glyphicons-halflings-regular.svg
----------------------------------------------------------------------
diff --git a/contrib/views/pig/src/main/resources/ui/pig-web/app/assets/fonts/glyphicons-halflings-regular.svg b/contrib/views/pig/src/main/resources/ui/pig-web/app/assets/fonts/glyphicons-halflings-regular.svg
new file mode 100644
index 0000000..4469488
--- /dev/null
+++ b/contrib/views/pig/src/main/resources/ui/pig-web/app/assets/fonts/glyphicons-halflings-regular.svg
@@ -0,0 +1,229 @@
+<?xml version="1.0" standalone="no"?>
+<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd" >
+<svg xmlns="http://www.w3.org/2000/svg">
+<metadata></metadata>
+<defs>
+<font id="glyphicons_halflingsregular" horiz-adv-x="1200" >
+<font-face units-per-em="1200" ascent="960" descent="-240" />
+<missing-glyph horiz-adv-x="500" />
+<glyph />
+<glyph />
+<glyph unicode="&#xd;" />
+<glyph unicode=" " />
+<glyph unicode="*" d="M100 500v200h259l-183 183l141 141l183 -183v259h200v-259l183 183l141 -141l-183 -183h259v-200h-259l183 -183l-141 -141l-183 183v-259h-200v259l-183 -183l-141 141l183 183h-259z" />
+<glyph unicode="+" d="M0 400v300h400v400h300v-400h400v-300h-400v-400h-300v400h-400z" />
+<glyph unicode="&#xa0;" />
+<glyph unicode="&#x2000;" horiz-adv-x="652" />
+<glyph unicode="&#x2001;" horiz-adv-x="1304" />
+<glyph unicode="&#x2002;" horiz-adv-x="652" />
+<glyph unicode="&#x2003;" horiz-adv-x="1304" />
+<glyph unicode="&#x2004;" horiz-adv-x="434" />
+<glyph unicode="&#x2005;" horiz-adv-x="326" />
+<glyph unicode="&#x2006;" horiz-adv-x="217" />
+<glyph unicode="&#x2007;" horiz-adv-x="217" />
+<glyph unicode="&#x2008;" horiz-adv-x="163" />
+<glyph unicode="&#x2009;" horiz-adv-x="260" />
+<glyph unicode="&#x200a;" horiz-adv-x="72" />
+<glyph unicode="&#x202f;" horiz-adv-x="260" />
+<glyph unicode="&#x205f;" horiz-adv-x="326" />
+<glyph unicode="&#x20ac;" d="M100 500l100 100h113q0 47 5 100h-218l100 100h135q37 167 112 257q117 141 297 141q242 0 354 -189q60 -103 66 -209h-181q0 55 -25.5 99t-63.5 68t-75 36.5t-67 12.5q-24 0 -52.5 -10t-62.5 -32t-65.5 -67t-50.5 -107h379l-100 -100h-300q-6 -46 -6 -100h406l-100 -100 h-300q9 -74 33 -132t52.5 -91t62 -54.5t59 -29t46.5 -7.5q29 0 66 13t75 37t63.5 67.5t25.5 96.5h174q-31 -172 -128 -278q-107 -117 -274 -117q-205 0 -324 158q-36 46 -69 131.5t-45 205.5h-217z" />
+<glyph unicode="&#x2212;" d="M200 400h900v300h-900v-300z" />
+<glyph unicode="&#x2601;" d="M-14 494q0 -80 56.5 -137t135.5 -57h750q120 0 205 86t85 208q0 120 -85 206.5t-205 86.5q-46 0 -90 -14q-44 97 -134.5 156.5t-200.5 59.5q-152 0 -260 -107.5t-108 -260.5q0 -25 2 -37q-66 -14 -108.5 -67.5t-42.5 -122.5z" />
+<glyph unicode="&#x2709;" d="M0 100l400 400l200 -200l200 200l400 -400h-1200zM0 300v600l300 -300zM0 1100l600 -603l600 603h-1200zM900 600l300 300v-600z" />
+<glyph unicode="&#x270f;" d="M-13 -13l333 112l-223 223zM187 403l214 -214l614 614l-214 214zM887 1103l214 -214l99 92q13 13 13 32.5t-13 33.5l-153 153q-15 13 -33 13t-33 -13z" />
+<glyph unicode="&#xe000;" horiz-adv-x="500" d="M0 0z" />
+<glyph unicode="&#xe001;" d="M0 1200h1200l-500 -550v-550h300v-100h-800v100h300v550z" />
+<glyph unicode="&#xe002;" d="M14 84q18 -55 86 -75.5t147 5.5q65 21 109 69t44 90v606l600 155v-521q-64 16 -138 -7q-79 -26 -122.5 -83t-25.5 -111q17 -55 85.5 -75.5t147.5 4.5q70 23 111.5 63.5t41.5 95.5v881q0 10 -7 15.5t-17 2.5l-752 -193q-10 -3 -17 -12.5t-7 -19.5v-689q-64 17 -138 -7 q-79 -25 -122.5 -82t-25.5 -112z" />
+<glyph unicode="&#xe003;" d="M23 693q0 200 142 342t342 142t342 -142t142 -342q0 -142 -78 -261l300 -300q7 -8 7 -18t-7 -18l-109 -109q-8 -7 -18 -7t-18 7l-300 300q-119 -78 -261 -78q-200 0 -342 142t-142 342zM176 693q0 -136 97 -233t234 -97t233.5 96.5t96.5 233.5t-96.5 233.5t-233.5 96.5 t-234 -97t-97 -233z" />
+<glyph unicode="&#xe005;" d="M100 784q0 64 28 123t73 100.5t104.5 64t119 20.5t120 -38.5t104.5 -104.5q48 69 109.5 105t121.5 38t118.5 -20.5t102.5 -64t71 -100.5t27 -123q0 -57 -33.5 -117.5t-94 -124.5t-126.5 -127.5t-150 -152.5t-146 -174q-62 85 -145.5 174t-149.5 152.5t-126.5 127.5 t-94 124.5t-33.5 117.5z" />
+<glyph unicode="&#xe006;" d="M-72 800h479l146 400h2l146 -400h472l-382 -278l145 -449l-384 275l-382 -275l146 447zM168 71l2 1z" />
+<glyph unicode="&#xe007;" d="M-72 800h479l146 400h2l146 -400h472l-382 -278l145 -449l-384 275l-382 -275l146 447zM168 71l2 1zM237 700l196 -142l-73 -226l192 140l195 -141l-74 229l193 140h-235l-77 211l-78 -211h-239z" />
+<glyph unicode="&#xe008;" d="M0 0v143l400 257v100q-37 0 -68.5 74.5t-31.5 125.5v200q0 124 88 212t212 88t212 -88t88 -212v-200q0 -51 -31.5 -125.5t-68.5 -74.5v-100l400 -257v-143h-1200z" />
+<glyph unicode="&#xe009;" d="M0 0v1100h1200v-1100h-1200zM100 100h100v100h-100v-100zM100 300h100v100h-100v-100zM100 500h100v100h-100v-100zM100 700h100v100h-100v-100zM100 900h100v100h-100v-100zM300 100h600v400h-600v-400zM300 600h600v400h-600v-400zM1000 100h100v100h-100v-100z M1000 300h100v100h-100v-100zM1000 500h100v100h-100v-100zM1000 700h100v100h-100v-100zM1000 900h100v100h-100v-100z" />
+<glyph unicode="&#xe010;" d="M0 50v400q0 21 14.5 35.5t35.5 14.5h400q21 0 35.5 -14.5t14.5 -35.5v-400q0 -21 -14.5 -35.5t-35.5 -14.5h-400q-21 0 -35.5 14.5t-14.5 35.5zM0 650v400q0 21 14.5 35.5t35.5 14.5h400q21 0 35.5 -14.5t14.5 -35.5v-400q0 -21 -14.5 -35.5t-35.5 -14.5h-400 q-21 0 -35.5 14.5t-14.5 35.5zM600 50v400q0 21 14.5 35.5t35.5 14.5h400q21 0 35.5 -14.5t14.5 -35.5v-400q0 -21 -14.5 -35.5t-35.5 -14.5h-400q-21 0 -35.5 14.5t-14.5 35.5zM600 650v400q0 21 14.5 35.5t35.5 14.5h400q21 0 35.5 -14.5t14.5 -35.5v-400 q0 -21 -14.5 -35.5t-35.5 -14.5h-400q-21 0 -35.5 14.5t-14.5 35.5z" />
+<glyph unicode="&#xe011;" d="M0 50v200q0 21 14.5 35.5t35.5 14.5h200q21 0 35.5 -14.5t14.5 -35.5v-200q0 -21 -14.5 -35.5t-35.5 -14.5h-200q-21 0 -35.5 14.5t-14.5 35.5zM0 450v200q0 21 14.5 35.5t35.5 14.5h200q21 0 35.5 -14.5t14.5 -35.5v-200q0 -21 -14.5 -35.5t-35.5 -14.5h-200 q-21 0 -35.5 14.5t-14.5 35.5zM0 850v200q0 21 14.5 35.5t35.5 14.5h200q21 0 35.5 -14.5t14.5 -35.5v-200q0 -21 -14.5 -35.5t-35.5 -14.5h-200q-21 0 -35.5 14.5t-14.5 35.5zM400 50v200q0 21 14.5 35.5t35.5 14.5h200q21 0 35.5 -14.5t14.5 -35.5v-200q0 -21 -14.5 -35.5 t-35.5 -14.5h-200q-21 0 -35.5 14.5t-14.5 35.5zM400 450v200q0 21 14.5 35.5t35.5 14.5h200q21 0 35.5 -14.5t14.5 -35.5v-200q0 -21 -14.5 -35.5t-35.5 -14.5h-200q-21 0 -35.5 14.5t-14.5 35.5zM400 850v200q0 21 14.5 35.5t35.5 14.5h200q21 0 35.5 -14.5t14.5 -35.5 v-200q0 -21 -14.5 -35.5t-35.5 -14.5h-200q-21 0 -35.5 14.5t-14.5 35.5zM800 50v200q0 21 14.5 35.5t35.5 14.5h200q21 0 35.5 -14.5t14.5 -35.5v-200q0 -21 -14.5 -35.5t-35.5 -14.5h-200q-21 0 -35.5 14.5t-14.5 35.5zM800 450v200q0 
 21 14.5 35.5t35.5 14.5h200 q21 0 35.5 -14.5t14.5 -35.5v-200q0 -21 -14.5 -35.5t-35.5 -14.5h-200q-21 0 -35.5 14.5t-14.5 35.5zM800 850v200q0 21 14.5 35.5t35.5 14.5h200q21 0 35.5 -14.5t14.5 -35.5v-200q0 -21 -14.5 -35.5t-35.5 -14.5h-200q-21 0 -35.5 14.5t-14.5 35.5z" />
+<glyph unicode="&#xe012;" d="M0 50v200q0 21 14.5 35.5t35.5 14.5h200q21 0 35.5 -14.5t14.5 -35.5v-200q0 -21 -14.5 -35.5t-35.5 -14.5h-200q-21 0 -35.5 14.5t-14.5 35.5zM0 450q0 -21 14.5 -35.5t35.5 -14.5h200q21 0 35.5 14.5t14.5 35.5v200q0 21 -14.5 35.5t-35.5 14.5h-200q-21 0 -35.5 -14.5 t-14.5 -35.5v-200zM0 850v200q0 21 14.5 35.5t35.5 14.5h200q21 0 35.5 -14.5t14.5 -35.5v-200q0 -21 -14.5 -35.5t-35.5 -14.5h-200q-21 0 -35.5 14.5t-14.5 35.5zM400 50v200q0 21 14.5 35.5t35.5 14.5h700q21 0 35.5 -14.5t14.5 -35.5v-200q0 -21 -14.5 -35.5 t-35.5 -14.5h-700q-21 0 -35.5 14.5t-14.5 35.5zM400 450v200q0 21 14.5 35.5t35.5 14.5h700q21 0 35.5 -14.5t14.5 -35.5v-200q0 -21 -14.5 -35.5t-35.5 -14.5h-700q-21 0 -35.5 14.5t-14.5 35.5zM400 850v200q0 21 14.5 35.5t35.5 14.5h700q21 0 35.5 -14.5t14.5 -35.5 v-200q0 -21 -14.5 -35.5t-35.5 -14.5h-700q-21 0 -35.5 14.5t-14.5 35.5z" />
+<glyph unicode="&#xe013;" d="M29 454l419 -420l818 820l-212 212l-607 -607l-206 207z" />
+<glyph unicode="&#xe014;" d="M106 318l282 282l-282 282l212 212l282 -282l282 282l212 -212l-282 -282l282 -282l-212 -212l-282 282l-282 -282z" />
+<glyph unicode="&#xe015;" d="M23 693q0 200 142 342t342 142t342 -142t142 -342q0 -142 -78 -261l300 -300q7 -8 7 -18t-7 -18l-109 -109q-8 -7 -18 -7t-18 7l-300 300q-119 -78 -261 -78q-200 0 -342 142t-142 342zM176 693q0 -136 97 -233t234 -97t233.5 96.5t96.5 233.5t-96.5 233.5t-233.5 96.5 t-234 -97t-97 -233zM300 600v200h100v100h200v-100h100v-200h-100v-100h-200v100h-100z" />
+<glyph unicode="&#xe016;" d="M23 694q0 200 142 342t342 142t342 -142t142 -342q0 -141 -78 -262l300 -299q7 -7 7 -18t-7 -18l-109 -109q-8 -8 -18 -8t-18 8l-300 299q-120 -77 -261 -77q-200 0 -342 142t-142 342zM176 694q0 -136 97 -233t234 -97t233.5 97t96.5 233t-96.5 233t-233.5 97t-234 -97 t-97 -233zM300 601h400v200h-400v-200z" />
+<glyph unicode="&#xe017;" d="M23 600q0 183 105 331t272 210v-166q-103 -55 -165 -155t-62 -220q0 -177 125 -302t302 -125t302 125t125 302q0 120 -62 220t-165 155v166q167 -62 272 -210t105 -331q0 -118 -45.5 -224.5t-123 -184t-184 -123t-224.5 -45.5t-224.5 45.5t-184 123t-123 184t-45.5 224.5 zM500 750q0 -21 14.5 -35.5t35.5 -14.5h100q21 0 35.5 14.5t14.5 35.5v400q0 21 -14.5 35.5t-35.5 14.5h-100q-21 0 -35.5 -14.5t-14.5 -35.5v-400z" />
+<glyph unicode="&#xe018;" d="M100 1h200v300h-200v-300zM400 1v500h200v-500h-200zM700 1v800h200v-800h-200zM1000 1v1200h200v-1200h-200z" />
+<glyph unicode="&#xe019;" d="M26 601q0 -33 6 -74l151 -38l2 -6q14 -49 38 -93l3 -5l-80 -134q45 -59 105 -105l133 81l5 -3q45 -26 94 -39l5 -2l38 -151q40 -5 74 -5q27 0 74 5l38 151l6 2q46 13 93 39l5 3l134 -81q56 44 104 105l-80 134l3 5q24 44 39 93l1 6l152 38q5 40 5 74q0 28 -5 73l-152 38 l-1 6q-16 51 -39 93l-3 5l80 134q-44 58 -104 105l-134 -81l-5 3q-45 25 -93 39l-6 1l-38 152q-40 5 -74 5q-27 0 -74 -5l-38 -152l-5 -1q-50 -14 -94 -39l-5 -3l-133 81q-59 -47 -105 -105l80 -134l-3 -5q-25 -47 -38 -93l-2 -6l-151 -38q-6 -48 -6 -73zM385 601 q0 88 63 151t152 63t152 -63t63 -151q0 -89 -63 -152t-152 -63t-152 63t-63 152z" />
+<glyph unicode="&#xe020;" d="M100 1025v50q0 10 7.5 17.5t17.5 7.5h275v100q0 41 29.5 70.5t70.5 29.5h300q41 0 70.5 -29.5t29.5 -70.5v-100h275q10 0 17.5 -7.5t7.5 -17.5v-50q0 -11 -7 -18t-18 -7h-1050q-11 0 -18 7t-7 18zM200 100v800h900v-800q0 -41 -29.5 -71t-70.5 -30h-700q-41 0 -70.5 30 t-29.5 71zM300 100h100v700h-100v-700zM500 100h100v700h-100v-700zM500 1100h300v100h-300v-100zM700 100h100v700h-100v-700zM900 100h100v700h-100v-700z" />
+<glyph unicode="&#xe021;" d="M1 601l656 644l644 -644h-200v-600h-300v400h-300v-400h-300v600h-200z" />
+<glyph unicode="&#xe022;" d="M100 25v1150q0 11 7 18t18 7h475v-500h400v-675q0 -11 -7 -18t-18 -7h-850q-11 0 -18 7t-7 18zM700 800v300l300 -300h-300z" />
+<glyph unicode="&#xe023;" d="M4 600q0 162 80 299t217 217t299 80t299 -80t217 -217t80 -299t-80 -299t-217 -217t-299 -80t-299 80t-217 217t-80 299zM186 600q0 -171 121.5 -292.5t292.5 -121.5t292.5 121.5t121.5 292.5t-121.5 292.5t-292.5 121.5t-292.5 -121.5t-121.5 -292.5zM500 500v400h100 v-300h200v-100h-300z" />
+<glyph unicode="&#xe024;" d="M-100 0l431 1200h209l-21 -300h162l-20 300h208l431 -1200h-538l-41 400h-242l-40 -400h-539zM488 500h224l-27 300h-170z" />
+<glyph unicode="&#xe025;" d="M0 0v400h490l-290 300h200v500h300v-500h200l-290 -300h490v-400h-1100zM813 200h175v100h-175v-100z" />
+<glyph unicode="&#xe026;" d="M1 600q0 122 47.5 233t127.5 191t191 127.5t233 47.5t233 -47.5t191 -127.5t127.5 -191t47.5 -233t-47.5 -233t-127.5 -191t-191 -127.5t-233 -47.5t-233 47.5t-191 127.5t-127.5 191t-47.5 233zM188 600q0 -170 121 -291t291 -121t291 121t121 291t-121 291t-291 121 t-291 -121t-121 -291zM350 600h150v300h200v-300h150l-250 -300z" />
+<glyph unicode="&#xe027;" d="M4 600q0 162 80 299t217 217t299 80t299 -80t217 -217t80 -299t-80 -299t-217 -217t-299 -80t-299 80t-217 217t-80 299zM186 600q0 -171 121.5 -292.5t292.5 -121.5t292.5 121.5t121.5 292.5t-121.5 292.5t-292.5 121.5t-292.5 -121.5t-121.5 -292.5zM350 600l250 300 l250 -300h-150v-300h-200v300h-150z" />
+<glyph unicode="&#xe028;" d="M0 25v475l200 700h800q199 -700 200 -700v-475q0 -11 -7 -18t-18 -7h-1150q-11 0 -18 7t-7 18zM200 500h200l50 -200h300l50 200h200l-97 500h-606z" />
+<glyph unicode="&#xe029;" d="M4 600q0 162 80 299t217 217t299 80t299 -80t217 -217t80 -299t-80 -299t-217 -217t-299 -80t-299 80t-217 217t-80 299zM186 600q0 -172 121.5 -293t292.5 -121t292.5 121t121.5 293q0 171 -121.5 292.5t-292.5 121.5t-292.5 -121.5t-121.5 -292.5zM500 397v401 l297 -200z" />
+<glyph unicode="&#xe030;" d="M23 600q0 -118 45.5 -224.5t123 -184t184 -123t224.5 -45.5t224.5 45.5t184 123t123 184t45.5 224.5h-150q0 -177 -125 -302t-302 -125t-302 125t-125 302t125 302t302 125q136 0 246 -81l-146 -146h400v400l-145 -145q-157 122 -355 122q-118 0 -224.5 -45.5t-184 -123 t-123 -184t-45.5 -224.5z" />
+<glyph unicode="&#xe031;" d="M23 600q0 118 45.5 224.5t123 184t184 123t224.5 45.5q198 0 355 -122l145 145v-400h-400l147 147q-112 80 -247 80q-177 0 -302 -125t-125 -302h-150zM100 0v400h400l-147 -147q112 -80 247 -80q177 0 302 125t125 302h150q0 -118 -45.5 -224.5t-123 -184t-184 -123 t-224.5 -45.5q-198 0 -355 122z" />
+<glyph unicode="&#xe032;" d="M100 0h1100v1200h-1100v-1200zM200 100v900h900v-900h-900zM300 200v100h100v-100h-100zM300 400v100h100v-100h-100zM300 600v100h100v-100h-100zM300 800v100h100v-100h-100zM500 200h500v100h-500v-100zM500 400v100h500v-100h-500zM500 600v100h500v-100h-500z M500 800v100h500v-100h-500z" />
+<glyph unicode="&#xe033;" d="M0 100v600q0 41 29.5 70.5t70.5 29.5h100v200q0 82 59 141t141 59h300q82 0 141 -59t59 -141v-200h100q41 0 70.5 -29.5t29.5 -70.5v-600q0 -41 -29.5 -70.5t-70.5 -29.5h-900q-41 0 -70.5 29.5t-29.5 70.5zM400 800h300v150q0 21 -14.5 35.5t-35.5 14.5h-200 q-21 0 -35.5 -14.5t-14.5 -35.5v-150z" />
+<glyph unicode="&#xe034;" d="M100 0v1100h100v-1100h-100zM300 400q60 60 127.5 84t127.5 17.5t122 -23t119 -30t110 -11t103 42t91 120.5v500q-40 -81 -101.5 -115.5t-127.5 -29.5t-138 25t-139.5 40t-125.5 25t-103 -29.5t-65 -115.5v-500z" />
+<glyph unicode="&#xe035;" d="M0 275q0 -11 7 -18t18 -7h50q11 0 18 7t7 18v300q0 127 70.5 231.5t184.5 161.5t245 57t245 -57t184.5 -161.5t70.5 -231.5v-300q0 -11 7 -18t18 -7h50q11 0 18 7t7 18v300q0 116 -49.5 227t-131 192.5t-192.5 131t-227 49.5t-227 -49.5t-192.5 -131t-131 -192.5 t-49.5 -227v-300zM200 20v460q0 8 6 14t14 6h160q8 0 14 -6t6 -14v-460q0 -8 -6 -14t-14 -6h-160q-8 0 -14 6t-6 14zM800 20v460q0 8 6 14t14 6h160q8 0 14 -6t6 -14v-460q0 -8 -6 -14t-14 -6h-160q-8 0 -14 6t-6 14z" />
+<glyph unicode="&#xe036;" d="M0 400h300l300 -200v800l-300 -200h-300v-400zM688 459l141 141l-141 141l71 71l141 -141l141 141l71 -71l-141 -141l141 -141l-71 -71l-141 141l-141 -141z" />
+<glyph unicode="&#xe037;" d="M0 400h300l300 -200v800l-300 -200h-300v-400zM700 857l69 53q111 -135 111 -310q0 -169 -106 -302l-67 54q86 110 86 248q0 146 -93 257z" />
+<glyph unicode="&#xe038;" d="M0 401v400h300l300 200v-800l-300 200h-300zM702 858l69 53q111 -135 111 -310q0 -170 -106 -303l-67 55q86 110 86 248q0 145 -93 257zM889 951l7 -8q123 -151 123 -344q0 -189 -119 -339l-7 -8l81 -66l6 8q142 178 142 405q0 230 -144 408l-6 8z" />
+<glyph unicode="&#xe039;" d="M0 0h500v500h-200v100h-100v-100h-200v-500zM0 600h100v100h400v100h100v100h-100v300h-500v-600zM100 100v300h300v-300h-300zM100 800v300h300v-300h-300zM200 200v100h100v-100h-100zM200 900h100v100h-100v-100zM500 500v100h300v-300h200v-100h-100v-100h-200v100 h-100v100h100v200h-200zM600 0v100h100v-100h-100zM600 1000h100v-300h200v-300h300v200h-200v100h200v500h-600v-200zM800 800v300h300v-300h-300zM900 0v100h300v-100h-300zM900 900v100h100v-100h-100zM1100 200v100h100v-100h-100z" />
+<glyph unicode="&#xe040;" d="M0 200h100v1000h-100v-1000zM100 0v100h300v-100h-300zM200 200v1000h100v-1000h-100zM500 0v91h100v-91h-100zM500 200v1000h200v-1000h-200zM700 0v91h100v-91h-100zM800 200v1000h100v-1000h-100zM900 0v91h200v-91h-200zM1000 200v1000h200v-1000h-200z" />
+<glyph unicode="&#xe041;" d="M1 700v475q0 10 7.5 17.5t17.5 7.5h474l700 -700l-500 -500zM148 953q0 -42 29 -71q30 -30 71.5 -30t71.5 30q29 29 29 71t-29 71q-30 30 -71.5 30t-71.5 -30q-29 -29 -29 -71z" />
+<glyph unicode="&#xe042;" d="M2 700v475q0 11 7 18t18 7h474l700 -700l-500 -500zM148 953q0 -42 30 -71q29 -30 71 -30t71 30q30 29 30 71t-30 71q-29 30 -71 30t-71 -30q-30 -29 -30 -71zM701 1200h100l700 -700l-500 -500l-50 50l450 450z" />
+<glyph unicode="&#xe043;" d="M100 0v1025l175 175h925v-1000l-100 -100v1000h-750l-100 -100h750v-1000h-900z" />
+<glyph unicode="&#xe044;" d="M200 0l450 444l450 -443v1150q0 20 -14.5 35t-35.5 15h-800q-21 0 -35.5 -15t-14.5 -35v-1151z" />
+<glyph unicode="&#xe045;" d="M0 100v700h200l100 -200h600l100 200h200v-700h-200v200h-800v-200h-200zM253 829l40 -124h592l62 124l-94 346q-2 11 -10 18t-18 7h-450q-10 0 -18 -7t-10 -18zM281 24l38 152q2 10 11.5 17t19.5 7h500q10 0 19.5 -7t11.5 -17l38 -152q2 -10 -3.5 -17t-15.5 -7h-600 q-10 0 -15.5 7t-3.5 17z" />
+<glyph unicode="&#xe046;" d="M0 200q0 -41 29.5 -70.5t70.5 -29.5h1000q41 0 70.5 29.5t29.5 70.5v600q0 41 -29.5 70.5t-70.5 29.5h-150q-4 8 -11.5 21.5t-33 48t-53 61t-69 48t-83.5 21.5h-200q-41 0 -82 -20.5t-70 -50t-52 -59t-34 -50.5l-12 -20h-150q-41 0 -70.5 -29.5t-29.5 -70.5v-600z M356 500q0 100 72 172t172 72t172 -72t72 -172t-72 -172t-172 -72t-172 72t-72 172zM494 500q0 -44 31 -75t75 -31t75 31t31 75t-31 75t-75 31t-75 -31t-31 -75zM900 700v100h100v-100h-100z" />
+<glyph unicode="&#xe047;" d="M53 0h365v66q-41 0 -72 11t-49 38t1 71l92 234h391l82 -222q16 -45 -5.5 -88.5t-74.5 -43.5v-66h417v66q-34 1 -74 43q-18 19 -33 42t-21 37l-6 13l-385 998h-93l-399 -1006q-24 -48 -52 -75q-12 -12 -33 -25t-36 -20l-15 -7v-66zM416 521l178 457l46 -140l116 -317h-340 z" />
+<glyph unicode="&#xe048;" d="M100 0v89q41 7 70.5 32.5t29.5 65.5v827q0 28 -1 39.5t-5.5 26t-15.5 21t-29 14t-49 14.5v70h471q120 0 213 -88t93 -228q0 -55 -11.5 -101.5t-28 -74t-33.5 -47.5t-28 -28l-12 -7q8 -3 21.5 -9t48 -31.5t60.5 -58t47.5 -91.5t21.5 -129q0 -84 -59 -156.5t-142 -111 t-162 -38.5h-500zM400 200h161q89 0 153 48.5t64 132.5q0 90 -62.5 154.5t-156.5 64.5h-159v-400zM400 700h139q76 0 130 61.5t54 138.5q0 82 -84 130.5t-239 48.5v-379z" />
+<glyph unicode="&#xe049;" d="M200 0v57q77 7 134.5 40.5t65.5 80.5l173 849q10 56 -10 74t-91 37q-6 1 -10.5 2.5t-9.5 2.5v57h425l2 -57q-33 -8 -62 -25.5t-46 -37t-29.5 -38t-17.5 -30.5l-5 -12l-128 -825q-10 -52 14 -82t95 -36v-57h-500z" />
+<glyph unicode="&#xe050;" d="M-75 200h75v800h-75l125 167l125 -167h-75v-800h75l-125 -167zM300 900v300h150h700h150v-300h-50q0 29 -8 48.5t-18.5 30t-33.5 15t-39.5 5.5t-50.5 1h-200v-850l100 -50v-100h-400v100l100 50v850h-200q-34 0 -50.5 -1t-40 -5.5t-33.5 -15t-18.5 -30t-8.5 -48.5h-49z " />
+<glyph unicode="&#xe051;" d="M33 51l167 125v-75h800v75l167 -125l-167 -125v75h-800v-75zM100 901v300h150h700h150v-300h-50q0 29 -8 48.5t-18 30t-33.5 15t-40 5.5t-50.5 1h-200v-650l100 -50v-100h-400v100l100 50v650h-200q-34 0 -50.5 -1t-39.5 -5.5t-33.5 -15t-18.5 -30t-8 -48.5h-50z" />
+<glyph unicode="&#xe052;" d="M0 50q0 -20 14.5 -35t35.5 -15h1100q21 0 35.5 15t14.5 35v100q0 21 -14.5 35.5t-35.5 14.5h-1100q-21 0 -35.5 -14.5t-14.5 -35.5v-100zM0 350q0 -20 14.5 -35t35.5 -15h800q21 0 35.5 15t14.5 35v100q0 21 -14.5 35.5t-35.5 14.5h-800q-21 0 -35.5 -14.5t-14.5 -35.5 v-100zM0 650q0 -20 14.5 -35t35.5 -15h1000q21 0 35.5 15t14.5 35v100q0 21 -14.5 35.5t-35.5 14.5h-1000q-21 0 -35.5 -14.5t-14.5 -35.5v-100zM0 950q0 -20 14.5 -35t35.5 -15h600q21 0 35.5 15t14.5 35v100q0 21 -14.5 35.5t-35.5 14.5h-600q-21 0 -35.5 -14.5 t-14.5 -35.5v-100z" />
+<glyph unicode="&#xe053;" d="M0 50q0 -20 14.5 -35t35.5 -15h1100q21 0 35.5 15t14.5 35v100q0 21 -14.5 35.5t-35.5 14.5h-1100q-21 0 -35.5 -14.5t-14.5 -35.5v-100zM0 650q0 -20 14.5 -35t35.5 -15h1100q21 0 35.5 15t14.5 35v100q0 21 -14.5 35.5t-35.5 14.5h-1100q-21 0 -35.5 -14.5t-14.5 -35.5 v-100zM200 350q0 -20 14.5 -35t35.5 -15h700q21 0 35.5 15t14.5 35v100q0 21 -14.5 35.5t-35.5 14.5h-700q-21 0 -35.5 -14.5t-14.5 -35.5v-100zM200 950q0 -20 14.5 -35t35.5 -15h700q21 0 35.5 15t14.5 35v100q0 21 -14.5 35.5t-35.5 14.5h-700q-21 0 -35.5 -14.5 t-14.5 -35.5v-100z" />
+<glyph unicode="&#xe054;" d="M0 50v100q0 21 14.5 35.5t35.5 14.5h1100q21 0 35.5 -14.5t14.5 -35.5v-100q0 -20 -14.5 -35t-35.5 -15h-1100q-21 0 -35.5 15t-14.5 35zM100 650v100q0 21 14.5 35.5t35.5 14.5h1000q21 0 35.5 -14.5t14.5 -35.5v-100q0 -20 -14.5 -35t-35.5 -15h-1000q-21 0 -35.5 15 t-14.5 35zM300 350v100q0 21 14.5 35.5t35.5 14.5h800q21 0 35.5 -14.5t14.5 -35.5v-100q0 -20 -14.5 -35t-35.5 -15h-800q-21 0 -35.5 15t-14.5 35zM500 950v100q0 21 14.5 35.5t35.5 14.5h600q21 0 35.5 -14.5t14.5 -35.5v-100q0 -20 -14.5 -35t-35.5 -15h-600 q-21 0 -35.5 15t-14.5 35z" />
+<glyph unicode="&#xe055;" d="M0 50v100q0 21 14.5 35.5t35.5 14.5h1100q21 0 35.5 -14.5t14.5 -35.5v-100q0 -20 -14.5 -35t-35.5 -15h-1100q-21 0 -35.5 15t-14.5 35zM0 350v100q0 21 14.5 35.5t35.5 14.5h1100q21 0 35.5 -14.5t14.5 -35.5v-100q0 -20 -14.5 -35t-35.5 -15h-1100q-21 0 -35.5 15 t-14.5 35zM0 650v100q0 21 14.5 35.5t35.5 14.5h1100q21 0 35.5 -14.5t14.5 -35.5v-100q0 -20 -14.5 -35t-35.5 -15h-1100q-21 0 -35.5 15t-14.5 35zM0 950v100q0 21 14.5 35.5t35.5 14.5h1100q21 0 35.5 -14.5t14.5 -35.5v-100q0 -20 -14.5 -35t-35.5 -15h-1100 q-21 0 -35.5 15t-14.5 35z" />
+<glyph unicode="&#xe056;" d="M0 50v100q0 21 14.5 35.5t35.5 14.5h100q21 0 35.5 -14.5t14.5 -35.5v-100q0 -20 -14.5 -35t-35.5 -15h-100q-21 0 -35.5 15t-14.5 35zM0 350v100q0 21 14.5 35.5t35.5 14.5h100q21 0 35.5 -14.5t14.5 -35.5v-100q0 -20 -14.5 -35t-35.5 -15h-100q-21 0 -35.5 15 t-14.5 35zM0 650v100q0 21 14.5 35.5t35.5 14.5h100q21 0 35.5 -14.5t14.5 -35.5v-100q0 -20 -14.5 -35t-35.5 -15h-100q-21 0 -35.5 15t-14.5 35zM0 950v100q0 21 14.5 35.5t35.5 14.5h100q21 0 35.5 -14.5t14.5 -35.5v-100q0 -20 -14.5 -35t-35.5 -15h-100q-21 0 -35.5 15 t-14.5 35zM300 50v100q0 21 14.5 35.5t35.5 14.5h800q21 0 35.5 -14.5t14.5 -35.5v-100q0 -20 -14.5 -35t-35.5 -15h-800q-21 0 -35.5 15t-14.5 35zM300 350v100q0 21 14.5 35.5t35.5 14.5h800q21 0 35.5 -14.5t14.5 -35.5v-100q0 -20 -14.5 -35t-35.5 -15h-800 q-21 0 -35.5 15t-14.5 35zM300 650v100q0 21 14.5 35.5t35.5 14.5h800q21 0 35.5 -14.5t14.5 -35.5v-100q0 -20 -14.5 -35t-35.5 -15h-800q-21 0 -35.5 15t-14.5 35zM300 950v100q0 21 14.5 35.5t35.5 14.5h800q21 0 35.5 -14.5t14.5 -35.5v-10
 0q0 -20 -14.5 -35t-35.5 -15 h-800q-21 0 -35.5 15t-14.5 35z" />
+<glyph unicode="&#xe057;" d="M-101 500v100h201v75l166 -125l-166 -125v75h-201zM300 0h100v1100h-100v-1100zM500 50q0 -20 14.5 -35t35.5 -15h600q20 0 35 15t15 35v100q0 21 -15 35.5t-35 14.5h-600q-21 0 -35.5 -14.5t-14.5 -35.5v-100zM500 350q0 -20 14.5 -35t35.5 -15h300q20 0 35 15t15 35 v100q0 21 -15 35.5t-35 14.5h-300q-21 0 -35.5 -14.5t-14.5 -35.5v-100zM500 650q0 -20 14.5 -35t35.5 -15h500q20 0 35 15t15 35v100q0 21 -15 35.5t-35 14.5h-500q-21 0 -35.5 -14.5t-14.5 -35.5v-100zM500 950q0 -20 14.5 -35t35.5 -15h100q20 0 35 15t15 35v100 q0 21 -15 35.5t-35 14.5h-100q-21 0 -35.5 -14.5t-14.5 -35.5v-100z" />
+<glyph unicode="&#xe058;" d="M1 50q0 -20 14.5 -35t35.5 -15h600q20 0 35 15t15 35v100q0 21 -15 35.5t-35 14.5h-600q-21 0 -35.5 -14.5t-14.5 -35.5v-100zM1 350q0 -20 14.5 -35t35.5 -15h300q20 0 35 15t15 35v100q0 21 -15 35.5t-35 14.5h-300q-21 0 -35.5 -14.5t-14.5 -35.5v-100zM1 650 q0 -20 14.5 -35t35.5 -15h500q20 0 35 15t15 35v100q0 21 -15 35.5t-35 14.5h-500q-21 0 -35.5 -14.5t-14.5 -35.5v-100zM1 950q0 -20 14.5 -35t35.5 -15h100q20 0 35 15t15 35v100q0 21 -15 35.5t-35 14.5h-100q-21 0 -35.5 -14.5t-14.5 -35.5v-100zM801 0v1100h100v-1100 h-100zM934 550l167 -125v75h200v100h-200v75z" />
+<glyph unicode="&#xe059;" d="M0 275v650q0 31 22 53t53 22h750q31 0 53 -22t22 -53v-650q0 -31 -22 -53t-53 -22h-750q-31 0 -53 22t-22 53zM900 600l300 300v-600z" />
+<glyph unicode="&#xe060;" d="M0 44v1012q0 18 13 31t31 13h1112q19 0 31.5 -13t12.5 -31v-1012q0 -18 -12.5 -31t-31.5 -13h-1112q-18 0 -31 13t-13 31zM100 263l247 182l298 -131l-74 156l293 318l236 -288v500h-1000v-737zM208 750q0 56 39 95t95 39t95 -39t39 -95t-39 -95t-95 -39t-95 39t-39 95z " />
+<glyph unicode="&#xe062;" d="M148 745q0 124 60.5 231.5t165 172t226.5 64.5q123 0 227 -63t164.5 -169.5t60.5 -229.5t-73 -272q-73 -114 -166.5 -237t-150.5 -189l-57 -66q-10 9 -27 26t-66.5 70.5t-96 109t-104 135.5t-100.5 155q-63 139 -63 262zM342 772q0 -107 75.5 -182.5t181.5 -75.5 q107 0 182.5 75.5t75.5 182.5t-75.5 182t-182.5 75t-182 -75.5t-75 -181.5z" />
+<glyph unicode="&#xe063;" d="M1 600q0 122 47.5 233t127.5 191t191 127.5t233 47.5t233 -47.5t191 -127.5t127.5 -191t47.5 -233t-47.5 -233t-127.5 -191t-191 -127.5t-233 -47.5t-233 47.5t-191 127.5t-127.5 191t-47.5 233zM173 600q0 -177 125.5 -302t301.5 -125v854q-176 0 -301.5 -125 t-125.5 -302z" />
+<glyph unicode="&#xe064;" d="M117 406q0 94 34 186t88.5 172.5t112 159t115 177t87.5 194.5q21 -71 57.5 -142.5t76 -130.5t83 -118.5t82 -117t70 -116t50 -125.5t18.5 -136q0 -89 -39 -165.5t-102 -126.5t-140 -79.5t-156 -33.5q-114 6 -211.5 53t-161.5 138.5t-64 210.5zM243 414q14 -82 59.5 -136 t136.5 -80l16 98q-7 6 -18 17t-34 48t-33 77q-15 73 -14 143.5t10 122.5l9 51q-92 -110 -119.5 -185t-12.5 -156z" />
+<glyph unicode="&#xe065;" d="M0 400v300q0 165 117.5 282.5t282.5 117.5q366 -6 397 -14l-186 -186h-311q-41 0 -70.5 -29.5t-29.5 -70.5v-500q0 -41 29.5 -70.5t70.5 -29.5h500q41 0 70.5 29.5t29.5 70.5v125l200 200v-225q0 -165 -117.5 -282.5t-282.5 -117.5h-300q-165 0 -282.5 117.5 t-117.5 282.5zM436 341l161 50l412 412l-114 113l-405 -405zM995 1015l113 -113l113 113l-21 85l-92 28z" />
+<glyph unicode="&#xe066;" d="M0 400v300q0 165 117.5 282.5t282.5 117.5h261l2 -80q-133 -32 -218 -120h-145q-41 0 -70.5 -29.5t-29.5 -70.5v-500q0 -41 29.5 -70.5t70.5 -29.5h500q41 0 70.5 29.5t29.5 70.5l200 153v-53q0 -165 -117.5 -282.5t-282.5 -117.5h-300q-165 0 -282.5 117.5t-117.5 282.5 zM423 524q30 38 81.5 64t103 35.5t99 14t77.5 3.5l29 -1v-209l360 324l-359 318v-216q-7 0 -19 -1t-48 -8t-69.5 -18.5t-76.5 -37t-76.5 -59t-62 -88t-39.5 -121.5z" />
+<glyph unicode="&#xe067;" d="M0 400v300q0 165 117.5 282.5t282.5 117.5h300q60 0 127 -23l-178 -177h-349q-41 0 -70.5 -29.5t-29.5 -70.5v-500q0 -41 29.5 -70.5t70.5 -29.5h500q41 0 70.5 29.5t29.5 70.5v69l200 200v-169q0 -165 -117.5 -282.5t-282.5 -117.5h-300q-165 0 -282.5 117.5 t-117.5 282.5zM342 632l283 -284l566 567l-136 137l-430 -431l-147 147z" />
+<glyph unicode="&#xe068;" d="M0 603l300 296v-198h200v200h-200l300 300l295 -300h-195v-200h200v198l300 -296l-300 -300v198h-200v-200h195l-295 -300l-300 300h200v200h-200v-198z" />
+<glyph unicode="&#xe069;" d="M200 50v1000q0 21 14.5 35.5t35.5 14.5h100q21 0 35.5 -14.5t14.5 -35.5v-437l500 487v-1100l-500 488v-438q0 -21 -14.5 -35.5t-35.5 -14.5h-100q-21 0 -35.5 14.5t-14.5 35.5z" />
+<glyph unicode="&#xe070;" d="M0 50v1000q0 21 14.5 35.5t35.5 14.5h100q21 0 35.5 -14.5t14.5 -35.5v-437l500 487v-487l500 487v-1100l-500 488v-488l-500 488v-438q0 -21 -14.5 -35.5t-35.5 -14.5h-100q-21 0 -35.5 14.5t-14.5 35.5z" />
+<glyph unicode="&#xe071;" d="M136 550l564 550v-487l500 487v-1100l-500 488v-488z" />
+<glyph unicode="&#xe072;" d="M200 0l900 550l-900 550v-1100z" />
+<glyph unicode="&#xe073;" d="M200 150q0 -21 14.5 -35.5t35.5 -14.5h200q21 0 35.5 14.5t14.5 35.5v800q0 21 -14.5 35.5t-35.5 14.5h-200q-21 0 -35.5 -14.5t-14.5 -35.5v-800zM600 150q0 -21 14.5 -35.5t35.5 -14.5h200q21 0 35.5 14.5t14.5 35.5v800q0 21 -14.5 35.5t-35.5 14.5h-200 q-21 0 -35.5 -14.5t-14.5 -35.5v-800z" />
+<glyph unicode="&#xe074;" d="M200 150q0 -20 14.5 -35t35.5 -15h800q21 0 35.5 15t14.5 35v800q0 21 -14.5 35.5t-35.5 14.5h-800q-21 0 -35.5 -14.5t-14.5 -35.5v-800z" />
+<glyph unicode="&#xe075;" d="M0 0v1100l500 -487v487l564 -550l-564 -550v488z" />
+<glyph unicode="&#xe076;" d="M0 0v1100l500 -487v487l500 -487v437q0 21 14.5 35.5t35.5 14.5h100q21 0 35.5 -14.5t14.5 -35.5v-1000q0 -21 -14.5 -35.5t-35.5 -14.5h-100q-21 0 -35.5 14.5t-14.5 35.5v438l-500 -488v488z" />
+<glyph unicode="&#xe077;" d="M300 0v1100l500 -487v437q0 21 14.5 35.5t35.5 14.5h100q21 0 35.5 -14.5t14.5 -35.5v-1000q0 -21 -14.5 -35.5t-35.5 -14.5h-100q-21 0 -35.5 14.5t-14.5 35.5v438z" />
+<glyph unicode="&#xe078;" d="M100 250v100q0 21 14.5 35.5t35.5 14.5h1000q21 0 35.5 -14.5t14.5 -35.5v-100q0 -21 -14.5 -35.5t-35.5 -14.5h-1000q-21 0 -35.5 14.5t-14.5 35.5zM100 500h1100l-550 564z" />
+<glyph unicode="&#xe079;" d="M185 599l592 -592l240 240l-353 353l353 353l-240 240z" />
+<glyph unicode="&#xe080;" d="M272 194l353 353l-353 353l241 240l572 -571l21 -22l-1 -1v-1l-592 -591z" />
+<glyph unicode="&#xe081;" d="M3 600q0 162 80 299.5t217.5 217.5t299.5 80t299.5 -80t217.5 -217.5t80 -299.5t-80 -300t-217.5 -218t-299.5 -80t-299.5 80t-217.5 218t-80 300zM300 500h200v-200h200v200h200v200h-200v200h-200v-200h-200v-200z" />
+<glyph unicode="&#xe082;" d="M3 600q0 162 80 299.5t217.5 217.5t299.5 80t299.5 -80t217.5 -217.5t80 -299.5t-80 -300t-217.5 -218t-299.5 -80t-299.5 80t-217.5 218t-80 300zM300 500h600v200h-600v-200z" />
+<glyph unicode="&#xe083;" d="M3 600q0 162 80 299.5t217.5 217.5t299.5 80t299.5 -80t217.5 -217.5t80 -299.5t-80 -300t-217.5 -218t-299.5 -80t-299.5 80t-217.5 218t-80 300zM246 459l213 -213l141 142l141 -142l213 213l-142 141l142 141l-213 212l-141 -141l-141 142l-212 -213l141 -141z" />
+<glyph unicode="&#xe084;" d="M3 600q0 162 80 299.5t217.5 217.5t299.5 80t299.5 -80t217.5 -217.5t80 -299.5t-80 -299.5t-217.5 -217.5t-299.5 -80t-299.5 80t-217.5 217.5t-80 299.5zM270 551l276 -277l411 411l-175 174l-236 -236l-102 102z" />
+<glyph unicode="&#xe085;" d="M3 600q0 162 80 299.5t217.5 217.5t299.5 80t299.5 -80t217.5 -217.5t80 -299.5t-80 -300t-217.5 -218t-299.5 -80t-299.5 80t-217.5 218t-80 300zM363 700h144q4 0 11.5 -1t11 -1t6.5 3t3 9t1 11t3.5 8.5t3.5 6t5.5 4t6.5 2.5t9 1.5t9 0.5h11.5h12.5q19 0 30 -10t11 -26 q0 -22 -4 -28t-27 -22q-5 -1 -12.5 -3t-27 -13.5t-34 -27t-26.5 -46t-11 -68.5h200q5 3 14 8t31.5 25.5t39.5 45.5t31 69t14 94q0 51 -17.5 89t-42 58t-58.5 32t-58.5 15t-51.5 3q-105 0 -172 -56t-67 -183zM500 300h200v100h-200v-100z" />
+<glyph unicode="&#xe086;" d="M3 600q0 162 80 299.5t217.5 217.5t299.5 80t299.5 -80t217.5 -217.5t80 -299.5t-80 -300t-217.5 -218t-299.5 -80t-299.5 80t-217.5 218t-80 300zM400 300h400v100h-100v300h-300v-100h100v-200h-100v-100zM500 800h200v100h-200v-100z" />
+<glyph unicode="&#xe087;" d="M0 500v200h194q15 60 36 104.5t55.5 86t88 69t126.5 40.5v200h200v-200q54 -20 113 -60t112.5 -105.5t71.5 -134.5h203v-200h-203q-25 -102 -116.5 -186t-180.5 -117v-197h-200v197q-140 27 -208 102.5t-98 200.5h-194zM290 500q24 -73 79.5 -127.5t130.5 -78.5v206h200 v-206q149 48 201 206h-201v200h200q-25 74 -76 127.5t-124 76.5v-204h-200v203q-75 -24 -130 -77.5t-79 -125.5h209v-200h-210z" />
+<glyph unicode="&#xe088;" d="M4 600q0 162 80 299t217 217t299 80t299 -80t217 -217t80 -299t-80 -299t-217 -217t-299 -80t-299 80t-217 217t-80 299zM186 600q0 -171 121.5 -292.5t292.5 -121.5t292.5 121.5t121.5 292.5t-121.5 292.5t-292.5 121.5t-292.5 -121.5t-121.5 -292.5zM356 465l135 135 l-135 135l109 109l135 -135l135 135l109 -109l-135 -135l135 -135l-109 -109l-135 135l-135 -135z" />
+<glyph unicode="&#xe089;" d="M4 600q0 162 80 299t217 217t299 80t299 -80t217 -217t80 -299t-80 -299t-217 -217t-299 -80t-299 80t-217 217t-80 299zM186 600q0 -171 121.5 -292.5t292.5 -121.5t292.5 121.5t121.5 292.5t-121.5 292.5t-292.5 121.5t-292.5 -121.5t-121.5 -292.5zM322 537l141 141 l87 -87l204 205l142 -142l-346 -345z" />
+<glyph unicode="&#xe090;" d="M4 600q0 162 80 299t217 217t299 80t299 -80t217 -217t80 -299t-80 -299t-217 -217t-299 -80t-299 80t-217 217t-80 299zM186 600q0 -115 62 -215l568 567q-100 62 -216 62q-171 0 -292.5 -121.5t-121.5 -292.5zM391 245q97 -59 209 -59q171 0 292.5 121.5t121.5 292.5 q0 112 -59 209z" />
+<glyph unicode="&#xe091;" d="M0 547l600 453v-300h600v-300h-600v-301z" />
+<glyph unicode="&#xe092;" d="M0 400v300h600v300l600 -453l-600 -448v301h-600z" />
+<glyph unicode="&#xe093;" d="M204 600l450 600l444 -600h-298v-600h-300v600h-296z" />
+<glyph unicode="&#xe094;" d="M104 600h296v600h300v-600h298l-449 -600z" />
+<glyph unicode="&#xe095;" d="M0 200q6 132 41 238.5t103.5 193t184 138t271.5 59.5v271l600 -453l-600 -448v301q-95 -2 -183 -20t-170 -52t-147 -92.5t-100 -135.5z" />
+<glyph unicode="&#xe096;" d="M0 0v400l129 -129l294 294l142 -142l-294 -294l129 -129h-400zM635 777l142 -142l294 294l129 -129v400h-400l129 -129z" />
+<glyph unicode="&#xe097;" d="M34 176l295 295l-129 129h400v-400l-129 130l-295 -295zM600 600v400l129 -129l295 295l142 -141l-295 -295l129 -130h-400z" />
+<glyph unicode="&#xe101;" d="M23 600q0 118 45.5 224.5t123 184t184 123t224.5 45.5t224.5 -45.5t184 -123t123 -184t45.5 -224.5t-45.5 -224.5t-123 -184t-184 -123t-224.5 -45.5t-224.5 45.5t-184 123t-123 184t-45.5 224.5zM456 851l58 -302q4 -20 21.5 -34.5t37.5 -14.5h54q20 0 37.5 14.5 t21.5 34.5l58 302q4 20 -8 34.5t-33 14.5h-207q-20 0 -32 -14.5t-8 -34.5zM500 300h200v100h-200v-100z" />
+<glyph unicode="&#xe102;" d="M0 800h100v-200h400v300h200v-300h400v200h100v100h-111v6t-1 15t-3 18l-34 172q-11 39 -41.5 63t-69.5 24q-32 0 -61 -17l-239 -144q-22 -13 -40 -35q-19 24 -40 36l-238 144q-33 18 -62 18q-39 0 -69.5 -23t-40.5 -61l-35 -177q-2 -8 -3 -18t-1 -15v-6h-111v-100z M100 0h400v400h-400v-400zM200 900q-3 0 14 48t35 96l18 47l214 -191h-281zM700 0v400h400v-400h-400zM731 900l202 197q5 -12 12 -32.5t23 -64t25 -72t7 -28.5h-269z" />
+<glyph unicode="&#xe103;" d="M0 -22v143l216 193q-9 53 -13 83t-5.5 94t9 113t38.5 114t74 124q47 60 99.5 102.5t103 68t127.5 48t145.5 37.5t184.5 43.5t220 58.5q0 -189 -22 -343t-59 -258t-89 -181.5t-108.5 -120t-122 -68t-125.5 -30t-121.5 -1.5t-107.5 12.5t-87.5 17t-56.5 7.5l-99 -55z M238.5 300.5q19.5 -6.5 86.5 76.5q55 66 367 234q70 38 118.5 69.5t102 79t99 111.5t86.5 148q22 50 24 60t-6 19q-7 5 -17 5t-26.5 -14.5t-33.5 -39.5q-35 -51 -113.5 -108.5t-139.5 -89.5l-61 -32q-369 -197 -458 -401q-48 -111 -28.5 -117.5z" />
+<glyph unicode="&#xe104;" d="M111 408q0 -33 5 -63q9 -56 44 -119.5t105 -108.5q31 -21 64 -16t62 23.5t57 49.5t48 61.5t35 60.5q32 66 39 184.5t-13 157.5q79 -80 122 -164t26 -184q-5 -33 -20.5 -69.5t-37.5 -80.5q-10 -19 -14.5 -29t-12 -26t-9 -23.5t-3 -19t2.5 -15.5t11 -9.5t19.5 -5t30.5 2.5 t42 8q57 20 91 34t87.5 44.5t87 64t65.5 88.5t47 122q38 172 -44.5 341.5t-246.5 278.5q22 -44 43 -129q39 -159 -32 -154q-15 2 -33 9q-79 33 -120.5 100t-44 175.5t48.5 257.5q-13 -8 -34 -23.5t-72.5 -66.5t-88.5 -105.5t-60 -138t-8 -166.5q2 -12 8 -41.5t8 -43t6 -39.5 t3.5 -39.5t-1 -33.5t-6 -31.5t-13.5 -24t-21 -20.5t-31 -12q-38 -10 -67 13t-40.5 61.5t-15 81.5t10.5 75q-52 -46 -83.5 -101t-39 -107t-7.5 -85z" />
+<glyph unicode="&#xe105;" d="M-61 600l26 40q6 10 20 30t49 63.5t74.5 85.5t97 90t116.5 83.5t132.5 59t145.5 23.5t145.5 -23.5t132.5 -59t116.5 -83.5t97 -90t74.5 -85.5t49 -63.5t20 -30l26 -40l-26 -40q-6 -10 -20 -30t-49 -63.5t-74.5 -85.5t-97 -90t-116.5 -83.5t-132.5 -59t-145.5 -23.5 t-145.5 23.5t-132.5 59t-116.5 83.5t-97 90t-74.5 85.5t-49 63.5t-20 30zM120 600q7 -10 40.5 -58t56 -78.5t68 -77.5t87.5 -75t103 -49.5t125 -21.5t123.5 20t100.5 45.5t85.5 71.5t66.5 75.5t58 81.5t47 66q-1 1 -28.5 37.5t-42 55t-43.5 53t-57.5 63.5t-58.5 54 q49 -74 49 -163q0 -124 -88 -212t-212 -88t-212 88t-88 212q0 85 46 158q-102 -87 -226 -258zM377 656q49 -124 154 -191l105 105q-37 24 -75 72t-57 84l-20 36z" />
+<glyph unicode="&#xe106;" d="M-61 600l26 40q6 10 20 30t49 63.5t74.5 85.5t97 90t116.5 83.5t132.5 59t145.5 23.5q61 0 121 -17l37 142h148l-314 -1200h-148l37 143q-82 21 -165 71.5t-140 102t-109.5 112t-72 88.5t-29.5 43zM120 600q210 -282 393 -336l37 141q-107 18 -178.5 101.5t-71.5 193.5 q0 85 46 158q-102 -87 -226 -258zM377 656q49 -124 154 -191l47 47l23 87q-30 28 -59 69t-44 68l-14 26zM780 161l38 145q22 15 44.5 34t46 44t40.5 44t41 50.5t33.5 43.5t33 44t24.5 34q-97 127 -140 175l39 146q67 -54 131.5 -125.5t87.5 -103.5t36 -52l26 -40l-26 -40 q-7 -12 -25.5 -38t-63.5 -79.5t-95.5 -102.5t-124 -100t-146.5 -79z" />
+<glyph unicode="&#xe107;" d="M-97.5 34q13.5 -34 50.5 -34h1294q37 0 50.5 35.5t-7.5 67.5l-642 1056q-20 33 -48 36t-48 -29l-642 -1066q-21 -32 -7.5 -66zM155 200l445 723l445 -723h-345v100h-200v-100h-345zM500 600l100 -300l100 300v100h-200v-100z" />
+<glyph unicode="&#xe108;" d="M100 262v41q0 20 11 44.5t26 38.5l363 325v339q0 62 44 106t106 44t106 -44t44 -106v-339l363 -325q15 -14 26 -38.5t11 -44.5v-41q0 -20 -12 -26.5t-29 5.5l-359 249v-263q100 -91 100 -113v-64q0 -21 -13 -29t-32 1l-94 78h-222l-94 -78q-19 -9 -32 -1t-13 29v64 q0 22 100 113v263l-359 -249q-17 -12 -29 -5.5t-12 26.5z" />
+<glyph unicode="&#xe109;" d="M0 50q0 -20 14.5 -35t35.5 -15h1000q21 0 35.5 15t14.5 35v750h-1100v-750zM0 900h1100v150q0 21 -14.5 35.5t-35.5 14.5h-150v100h-100v-100h-500v100h-100v-100h-150q-21 0 -35.5 -14.5t-14.5 -35.5v-150zM100 100v100h100v-100h-100zM100 300v100h100v-100h-100z M100 500v100h100v-100h-100zM300 100v100h100v-100h-100zM300 300v100h100v-100h-100zM300 500v100h100v-100h-100zM500 100v100h100v-100h-100zM500 300v100h100v-100h-100zM500 500v100h100v-100h-100zM700 100v100h100v-100h-100zM700 300v100h100v-100h-100zM700 500 v100h100v-100h-100zM900 100v100h100v-100h-100zM900 300v100h100v-100h-100zM900 500v100h100v-100h-100z" />
+<glyph unicode="&#xe110;" d="M0 200v200h259l600 600h241v198l300 -295l-300 -300v197h-159l-600 -600h-341zM0 800h259l122 -122l141 142l-181 180h-341v-200zM678 381l141 142l122 -123h159v198l300 -295l-300 -300v197h-241z" />
+<glyph unicode="&#xe111;" d="M0 400v600q0 41 29.5 70.5t70.5 29.5h1000q41 0 70.5 -29.5t29.5 -70.5v-600q0 -41 -29.5 -70.5t-70.5 -29.5h-596l-304 -300v300h-100q-41 0 -70.5 29.5t-29.5 70.5z" />
+<glyph unicode="&#xe112;" d="M100 600v200h300v-250q0 -113 6 -145q17 -92 102 -117q39 -11 92 -11q37 0 66.5 5.5t50 15.5t36 24t24 31.5t14 37.5t7 42t2.5 45t0 47v25v250h300v-200q0 -42 -3 -83t-15 -104t-31.5 -116t-58 -109.5t-89 -96.5t-129 -65.5t-174.5 -25.5t-174.5 25.5t-129 65.5t-89 96.5 t-58 109.5t-31.5 116t-15 104t-3 83zM100 900v300h300v-300h-300zM800 900v300h300v-300h-300z" />
+<glyph unicode="&#xe113;" d="M-30 411l227 -227l352 353l353 -353l226 227l-578 579z" />
+<glyph unicode="&#xe114;" d="M70 797l580 -579l578 579l-226 227l-353 -353l-352 353z" />
+<glyph unicode="&#xe115;" d="M-198 700l299 283l300 -283h-203v-400h385l215 -200h-800v600h-196zM402 1000l215 -200h381v-400h-198l299 -283l299 283h-200v600h-796z" />
+<glyph unicode="&#xe116;" d="M18 939q-5 24 10 42q14 19 39 19h896l38 162q5 17 18.5 27.5t30.5 10.5h94q20 0 35 -14.5t15 -35.5t-15 -35.5t-35 -14.5h-54l-201 -961q-2 -4 -6 -10.5t-19 -17.5t-33 -11h-31v-50q0 -20 -14.5 -35t-35.5 -15t-35.5 15t-14.5 35v50h-300v-50q0 -20 -14.5 -35t-35.5 -15 t-35.5 15t-14.5 35v50h-50q-21 0 -35.5 15t-14.5 35q0 21 14.5 35.5t35.5 14.5h535l48 200h-633q-32 0 -54.5 21t-27.5 43z" />
+<glyph unicode="&#xe117;" d="M0 0v800h1200v-800h-1200zM0 900v100h200q0 41 29.5 70.5t70.5 29.5h300q41 0 70.5 -29.5t29.5 -70.5h500v-100h-1200z" />
+<glyph unicode="&#xe118;" d="M1 0l300 700h1200l-300 -700h-1200zM1 400v600h200q0 41 29.5 70.5t70.5 29.5h300q41 0 70.5 -29.5t29.5 -70.5h500v-200h-1000z" />
+<glyph unicode="&#xe119;" d="M302 300h198v600h-198l298 300l298 -300h-198v-600h198l-298 -300z" />
+<glyph unicode="&#xe120;" d="M0 600l300 298v-198h600v198l300 -298l-300 -297v197h-600v-197z" />
+<glyph unicode="&#xe121;" d="M0 100v100q0 41 29.5 70.5t70.5 29.5h1000q41 0 70.5 -29.5t29.5 -70.5v-100q0 -41 -29.5 -70.5t-70.5 -29.5h-1000q-41 0 -70.5 29.5t-29.5 70.5zM31 400l172 739q5 22 23 41.5t38 19.5h672q19 0 37.5 -22.5t23.5 -45.5l172 -732h-1138zM800 100h100v100h-100v-100z M1000 100h100v100h-100v-100z" />
+<glyph unicode="&#xe122;" d="M-101 600v50q0 24 25 49t50 38l25 13v-250l-11 5.5t-24 14t-30 21.5t-24 27.5t-11 31.5zM99 500v250v5q0 13 0.5 18.5t2.5 13t8 10.5t15 3h200l675 250v-850l-675 200h-38l47 -276q2 -12 -3 -17.5t-11 -6t-21 -0.5h-8h-83q-20 0 -34.5 14t-18.5 35q-56 337 -56 351z M1100 200v850q0 21 14.5 35.5t35.5 14.5q20 0 35 -14.5t15 -35.5v-850q0 -20 -15 -35t-35 -15q-21 0 -35.5 15t-14.5 35z" />
+<glyph unicode="&#xe123;" d="M74 350q0 21 13.5 35.5t33.5 14.5h17l118 173l63 327q15 77 76 140t144 83l-18 32q-6 19 3 32t29 13h94q20 0 29 -10.5t3 -29.5l-18 -37q83 -19 144 -82.5t76 -140.5l63 -327l118 -173h17q20 0 33.5 -14.5t13.5 -35.5q0 -20 -13 -40t-31 -27q-22 -9 -63 -23t-167.5 -37 t-251.5 -23t-245.5 20.5t-178.5 41.5l-58 20q-18 7 -31 27.5t-13 40.5zM497 110q12 -49 40 -79.5t63 -30.5t63 30.5t39 79.5q-48 -6 -102 -6t-103 6z" />
+<glyph unicode="&#xe124;" d="M21 445l233 -45l-78 -224l224 78l45 -233l155 179l155 -179l45 233l224 -78l-78 224l234 45l-180 155l180 156l-234 44l78 225l-224 -78l-45 233l-155 -180l-155 180l-45 -233l-224 78l78 -225l-233 -44l179 -156z" />
+<glyph unicode="&#xe125;" d="M0 200h200v600h-200v-600zM300 275q0 -75 100 -75h61q123 -100 139 -100h250q46 0 83 57l238 344q29 31 29 74v100q0 44 -30.5 84.5t-69.5 40.5h-328q28 118 28 125v150q0 44 -30.5 84.5t-69.5 40.5h-50q-27 0 -51 -20t-38 -48l-96 -198l-145 -196q-20 -26 -20 -63v-400z M400 300v375l150 212l100 213h50v-175l-50 -225h450v-125l-250 -375h-214l-136 100h-100z" />
+<glyph unicode="&#xe126;" d="M0 400v600h200v-600h-200zM300 525v400q0 75 100 75h61q123 100 139 100h250q46 0 83 -57l238 -344q29 -31 29 -74v-100q0 -44 -30.5 -84.5t-69.5 -40.5h-328q28 -118 28 -125v-150q0 -44 -30.5 -84.5t-69.5 -40.5h-50q-27 0 -51 20t-38 48l-96 198l-145 196 q-20 26 -20 63zM400 525l150 -212l100 -213h50v175l-50 225h450v125l-250 375h-214l-136 -100h-100v-375z" />
+<glyph unicode="&#xe127;" d="M8 200v600h200v-600h-200zM308 275v525q0 17 14 35.5t28 28.5l14 9l362 230q14 6 25 6q17 0 29 -12l109 -112q14 -14 14 -34q0 -18 -11 -32l-85 -121h302q85 0 138.5 -38t53.5 -110t-54.5 -111t-138.5 -39h-107l-130 -339q-7 -22 -20.5 -41.5t-28.5 -19.5h-341 q-7 0 -90 81t-83 94zM408 289l100 -89h293l131 339q6 21 19.5 41t28.5 20h203q16 0 25 15t9 36q0 20 -9 34.5t-25 14.5h-457h-6.5h-7.5t-6.5 0.5t-6 1t-5 1.5t-5.5 2.5t-4 4t-4 5.5q-5 12 -5 20q0 14 10 27l147 183l-86 83l-339 -236v-503z" />
+<glyph unicode="&#xe128;" d="M-101 651q0 72 54 110t139 37h302l-85 121q-11 16 -11 32q0 21 14 34l109 113q13 12 29 12q11 0 25 -6l365 -230q7 -4 16.5 -10.5t26 -26t16.5 -36.5v-526q0 -13 -85.5 -93.5t-93.5 -80.5h-342q-15 0 -28.5 20t-19.5 41l-131 339h-106q-84 0 -139 39t-55 111zM-1 601h222 q15 0 28.5 -20.5t19.5 -40.5l131 -339h293l106 89v502l-342 237l-87 -83l145 -184q10 -11 10 -26q0 -11 -5 -20q-1 -3 -3.5 -5.5l-4 -4t-5 -2.5t-5.5 -1.5t-6.5 -1t-6.5 -0.5h-7.5h-6.5h-476v-100zM999 201v600h200v-600h-200z" />
+<glyph unicode="&#xe129;" d="M97 719l230 -363q4 -6 10.5 -15.5t26 -25t36.5 -15.5h525q13 0 94 83t81 90v342q0 15 -20 28.5t-41 19.5l-339 131v106q0 84 -39 139t-111 55t-110 -53.5t-38 -138.5v-302l-121 84q-15 12 -33.5 11.5t-32.5 -13.5l-112 -110q-22 -22 -6 -53zM172 739l83 86l183 -146 q22 -18 47 -5q3 1 5.5 3.5l4 4t2.5 5t1.5 5.5t1 6.5t0.5 6v7.5v7v456q0 22 25 31t50 -0.5t25 -30.5v-202q0 -16 20 -29.5t41 -19.5l339 -130v-294l-89 -100h-503zM400 0v200h600v-200h-600z" />
+<glyph unicode="&#xe130;" d="M1 585q-15 -31 7 -53l112 -110q13 -13 32 -13.5t34 10.5l121 85l-1 -302q0 -84 38.5 -138t110.5 -54t111 55t39 139v106l339 131q20 6 40.5 19.5t20.5 28.5v342q0 7 -81 90t-94 83h-525q-17 0 -35.5 -14t-28.5 -28l-10 -15zM76 565l237 339h503l89 -100v-294l-340 -130 q-20 -6 -40 -20t-20 -29v-202q0 -22 -25 -31t-50 0t-25 31v456v14.5t-1.5 11.5t-5 12t-9.5 7q-24 13 -46 -5l-184 -146zM305 1104v200h600v-200h-600z" />
+<glyph unicode="&#xe131;" d="M5 597q0 122 47.5 232.5t127.5 190.5t190.5 127.5t232.5 47.5q162 0 299.5 -80t217.5 -218t80 -300t-80 -299.5t-217.5 -217.5t-299.5 -80t-300 80t-218 217.5t-80 299.5zM300 500h300l-2 -194l402 294l-402 298v-197h-298v-201z" />
+<glyph unicode="&#xe132;" d="M0 597q0 122 47.5 232.5t127.5 190.5t190.5 127.5t231.5 47.5q122 0 232.5 -47.5t190.5 -127.5t127.5 -190.5t47.5 -232.5q0 -162 -80 -299.5t-218 -217.5t-300 -80t-299.5 80t-217.5 217.5t-80 299.5zM200 600l400 -294v194h302v201h-300v197z" />
+<glyph unicode="&#xe133;" d="M5 597q0 122 47.5 232.5t127.5 190.5t190.5 127.5t232.5 47.5q121 0 231.5 -47.5t190.5 -127.5t127.5 -190.5t47.5 -232.5q0 -162 -80 -299.5t-217.5 -217.5t-299.5 -80t-300 80t-218 217.5t-80 299.5zM300 600h200v-300h200v300h200l-300 400z" />
+<glyph unicode="&#xe134;" d="M5 597q0 122 47.5 232.5t127.5 190.5t190.5 127.5t232.5 47.5q121 0 231.5 -47.5t190.5 -127.5t127.5 -190.5t47.5 -232.5q0 -162 -80 -299.5t-217.5 -217.5t-299.5 -80t-300 80t-218 217.5t-80 299.5zM300 600l300 -400l300 400h-200v300h-200v-300h-200z" />
+<glyph unicode="&#xe135;" d="M5 597q0 122 47.5 232.5t127.5 190.5t190.5 127.5t232.5 47.5q121 0 231.5 -47.5t190.5 -127.5t127.5 -190.5t47.5 -232.5q0 -162 -80 -299.5t-217.5 -217.5t-299.5 -80t-300 80t-218 217.5t-80 299.5zM254 780q-8 -34 5.5 -93t7.5 -87q0 -9 17 -44t16 -60q12 0 23 -5.5 t23 -15t20 -13.5q20 -10 108 -42q22 -8 53 -31.5t59.5 -38.5t57.5 -11q8 -18 -15 -55.5t-20 -57.5q12 -21 22.5 -34.5t28 -27t36.5 -17.5q0 -6 -3 -15.5t-3.5 -14.5t4.5 -17q101 -2 221 111q31 30 47 48t34 49t21 62q-14 9 -37.5 9.5t-35.5 7.5q-14 7 -49 15t-52 19 q-9 0 -39.5 -0.5t-46.5 -1.5t-39 -6.5t-39 -16.5q-50 -35 -66 -12q-4 2 -3.5 25.5t0.5 25.5q-6 13 -26.5 17t-24.5 7q2 22 -2 41t-16.5 28t-38.5 -20q-23 -25 -42 4q-19 28 -8 58q8 16 22 22q6 -1 26 -1.5t33.5 -4.5t19.5 -13q12 -19 32 -37.5t34 -27.5l14 -8q0 3 9.5 39.5 t5.5 57.5q-4 23 14.5 44.5t22.5 31.5q5 14 10 35t8.5 31t15.5 22.5t34 21.5q-6 18 10 37q8 0 23.5 -1.5t24.5 -1.5t20.5 4.5t20.5 15.5q-10 23 -30.5 42.5t-38 30t-49 26.5t-43.5 23q11 41 1 44q31 -13 58.5 -14.5t39.5 3.5l11 4q6 3
 6 -17 53.5t-64 28.5t-56 23 q-19 -3 -37 0q-15 -12 -36.5 -21t-34.5 -12t-44 -8t-39 -6q-15 -3 -46 0t-45 -3q-20 -6 -51.5 -25.5t-34.5 -34.5q-3 -11 6.5 -22.5t8.5 -18.5q-3 -34 -27.5 -91t-29.5 -79zM518 915q3 12 16 30.5t16 25.5q10 -10 18.5 -10t14 6t14.5 14.5t16 12.5q0 -18 8 -42.5t16.5 -44 t9.5 -23.5q-6 1 -39 5t-53.5 10t-36.5 16z" />
+<glyph unicode="&#xe136;" d="M0 164.5q0 21.5 15 37.5l600 599q-33 101 6 201.5t135 154.5q164 92 306 -9l-259 -138l145 -232l251 126q13 -175 -151 -267q-123 -70 -253 -23l-596 -596q-15 -16 -36.5 -16t-36.5 16l-111 110q-15 15 -15 36.5z" />
+<glyph unicode="&#xe137;" horiz-adv-x="1220" d="M0 196v100q0 41 29.5 70.5t70.5 29.5h1000q41 0 70.5 -29.5t29.5 -70.5v-100q0 -41 -29.5 -70.5t-70.5 -29.5h-1000q-41 0 -70.5 29.5t-29.5 70.5zM0 596v100q0 41 29.5 70.5t70.5 29.5h1000q41 0 70.5 -29.5t29.5 -70.5v-100q0 -41 -29.5 -70.5t-70.5 -29.5h-1000 q-41 0 -70.5 29.5t-29.5 70.5zM0 996v100q0 41 29.5 70.5t70.5 29.5h1000q41 0 70.5 -29.5t29.5 -70.5v-100q0 -41 -29.5 -70.5t-70.5 -29.5h-1000q-41 0 -70.5 29.5t-29.5 70.5zM600 596h500v100h-500v-100zM800 196h300v100h-300v-100zM900 996h200v100h-200v-100z" />
+<glyph unicode="&#xe138;" d="M100 1100v100h1000v-100h-1000zM150 1000h900l-350 -500v-300l-200 -200v500z" />
+<glyph unicode="&#xe139;" d="M0 200v200h1200v-200q0 -41 -29.5 -70.5t-70.5 -29.5h-1000q-41 0 -70.5 29.5t-29.5 70.5zM0 500v400q0 41 29.5 70.5t70.5 29.5h300v100q0 41 29.5 70.5t70.5 29.5h200q41 0 70.5 -29.5t29.5 -70.5v-100h300q41 0 70.5 -29.5t29.5 -70.5v-400h-500v100h-200v-100h-500z M500 1000h200v100h-200v-100z" />
+<glyph unicode="&#xe140;" d="M0 0v400l129 -129l200 200l142 -142l-200 -200l129 -129h-400zM0 800l129 129l200 -200l142 142l-200 200l129 129h-400v-400zM729 329l142 142l200 -200l129 129v-400h-400l129 129zM729 871l200 200l-129 129h400v-400l-129 129l-200 -200z" />
+<glyph unicode="&#xe141;" d="M0 596q0 162 80 299t217 217t299 80t299 -80t217 -217t80 -299t-80 -299t-217 -217t-299 -80t-299 80t-217 217t-80 299zM182 596q0 -172 121.5 -293t292.5 -121t292.5 121t121.5 293q0 171 -121.5 292.5t-292.5 121.5t-292.5 -121.5t-121.5 -292.5zM291 655 q0 23 15.5 38.5t38.5 15.5t39 -16t16 -38q0 -23 -16 -39t-39 -16q-22 0 -38 16t-16 39zM400 850q0 22 16 38.5t39 16.5q22 0 38 -16t16 -39t-16 -39t-38 -16q-23 0 -39 16.5t-16 38.5zM513 609q0 32 21 56.5t52 29.5l122 126l1 1q-9 14 -9 28q0 22 16 38.5t39 16.5 q22 0 38 -16t16 -39t-16 -39t-38 -16q-16 0 -29 10l-55 -145q17 -22 17 -51q0 -36 -25.5 -61.5t-61.5 -25.5q-37 0 -62.5 25.5t-25.5 61.5zM800 655q0 22 16 38t39 16t38.5 -15.5t15.5 -38.5t-16 -39t-38 -16q-23 0 -39 16t-16 39z" />
+<glyph unicode="&#xe142;" d="M-40 375q-13 -95 35 -173q35 -57 94 -89t129 -32q63 0 119 28q33 16 65 40.5t52.5 45.5t59.5 64q40 44 57 61l394 394q35 35 47 84t-3 96q-27 87 -117 104q-20 2 -29 2q-46 0 -79.5 -17t-67.5 -51l-388 -396l-7 -7l69 -67l377 373q20 22 39 38q23 23 50 23q38 0 53 -36 q16 -39 -20 -75l-547 -547q-52 -52 -125 -52q-55 0 -100 33t-54 96q-5 35 2.5 66t31.5 63t42 50t56 54q24 21 44 41l348 348q52 52 82.5 79.5t84 54t107.5 26.5q25 0 48 -4q95 -17 154 -94.5t51 -175.5q-7 -101 -98 -192l-252 -249l-253 -256l7 -7l69 -60l517 511 q67 67 95 157t11 183q-16 87 -67 154t-130 103q-69 33 -152 33q-107 0 -197 -55q-40 -24 -111 -95l-512 -512q-68 -68 -81 -163z" />
+<glyph unicode="&#xe143;" d="M79 784q0 131 99 229.5t230 98.5q144 0 242 -129q103 129 245 129q130 0 227 -98.5t97 -229.5q0 -46 -17.5 -91t-61 -99t-77 -89.5t-104.5 -105.5q-197 -191 -293 -322l-17 -23l-16 23q-43 58 -100 122.5t-92 99.5t-101 100l-84.5 84.5t-68 74t-60 78t-33.5 70.5t-15 78z M250 784q0 -27 30.5 -70t61.5 -75.5t95 -94.5l22 -22q93 -90 190 -201q82 92 195 203l12 12q64 62 97.5 97t64.5 79t31 72q0 71 -48 119.5t-106 48.5q-73 0 -131 -83l-118 -171l-114 174q-51 80 -124 80q-59 0 -108.5 -49.5t-49.5 -118.5z" />
+<glyph unicode="&#xe144;" d="M57 353q0 -94 66 -160l141 -141q66 -66 159 -66q95 0 159 66l283 283q66 66 66 159t-66 159l-141 141q-12 12 -19 17l-105 -105l212 -212l-389 -389l-247 248l95 95l-18 18q-46 45 -75 101l-55 -55q-66 -66 -66 -159zM269 706q0 -93 66 -159l141 -141l19 -17l105 105 l-212 212l389 389l247 -247l-95 -96l18 -18q46 -46 77 -99l29 29q35 35 62.5 88t27.5 96q0 93 -66 159l-141 141q-66 66 -159 66q-95 0 -159 -66l-283 -283q-66 -64 -66 -159z" />
+<glyph unicode="&#xe145;" d="M200 100v953q0 21 30 46t81 48t129 38t163 15t162 -15t127 -38t79 -48t29 -46v-953q0 -41 -29.5 -70.5t-70.5 -29.5h-600q-41 0 -70.5 29.5t-29.5 70.5zM300 300h600v700h-600v-700zM496 150q0 -43 30.5 -73.5t73.5 -30.5t73.5 30.5t30.5 73.5t-30.5 73.5t-73.5 30.5 t-73.5 -30.5t-30.5 -73.5z" />
+<glyph unicode="&#xe146;" d="M0 0l303 380l207 208l-210 212h300l267 279l-35 36q-15 14 -15 35t15 35q14 15 35 15t35 -15l283 -282q15 -15 15 -36t-15 -35q-14 -15 -35 -15t-35 15l-36 35l-279 -267v-300l-212 210l-208 -207z" />
+<glyph unicode="&#xe148;" d="M295 433h139q5 -77 48.5 -126.5t117.5 -64.5v335l-27 7q-46 14 -79 26.5t-72 36t-62.5 52t-40 72.5t-16.5 99q0 92 44 159.5t109 101t144 40.5v78h100v-79q38 -4 72.5 -13.5t75.5 -31.5t71 -53.5t51.5 -84t24.5 -118.5h-159q-8 72 -35 109.5t-101 50.5v-307l64 -14 q34 -7 64 -16.5t70 -31.5t67.5 -52t47.5 -80.5t20 -112.5q0 -139 -89 -224t-244 -96v-77h-100v78q-152 17 -237 104q-40 40 -52.5 93.5t-15.5 139.5zM466 889q0 -29 8 -51t16.5 -34t29.5 -22.5t31 -13.5t38 -10q7 -2 11 -3v274q-61 -8 -97.5 -37.5t-36.5 -102.5zM700 237 q170 18 170 151q0 64 -44 99.5t-126 60.5v-311z" />
+<glyph unicode="&#xe149;" d="M100 600v100h166q-24 49 -44 104q-10 26 -14.5 55.5t-3 72.5t25 90t68.5 87q97 88 263 88q129 0 230 -89t101 -208h-153q0 52 -34 89.5t-74 51.5t-76 14q-37 0 -79 -14.5t-62 -35.5q-41 -44 -41 -101q0 -11 2.5 -24.5t5.5 -24t9.5 -26.5t10.5 -25t14 -27.5t14 -25.5 t15.5 -27t13.5 -24h242v-100h-197q8 -50 -2.5 -115t-31.5 -94q-41 -59 -99 -113q35 11 84 18t70 7q32 1 102 -16t104 -17q76 0 136 30l50 -147q-41 -25 -80.5 -36.5t-59 -13t-61.5 -1.5q-23 0 -128 33t-155 29q-39 -4 -82 -17t-66 -25l-24 -11l-55 145l16.5 11t15.5 10 t13.5 9.5t14.5 12t14.5 14t17.5 18.5q48 55 54 126.5t-30 142.5h-221z" />
+<glyph unicode="&#xe150;" d="M2 300l298 -300l298 300h-198v900h-200v-900h-198zM602 900l298 300l298 -300h-198v-900h-200v900h-198z" />
+<glyph unicode="&#xe151;" d="M2 300h198v900h200v-900h198l-298 -300zM700 0v200h100v-100h200v-100h-300zM700 400v100h300v-200h-99v-100h-100v100h99v100h-200zM700 700v500h300v-500h-100v100h-100v-100h-100zM801 900h100v200h-100v-200z" />
+<glyph unicode="&#xe152;" d="M2 300h198v900h200v-900h198l-298 -300zM700 0v500h300v-500h-100v100h-100v-100h-100zM700 700v200h100v-100h200v-100h-300zM700 1100v100h300v-200h-99v-100h-100v100h99v100h-200zM801 200h100v200h-100v-200z" />
+<glyph unicode="&#xe153;" d="M2 300l298 -300l298 300h-198v900h-200v-900h-198zM800 100v400h300v-500h-100v100h-200zM800 1100v100h200v-500h-100v400h-100zM901 200h100v200h-100v-200z" />
+<glyph unicode="&#xe154;" d="M2 300l298 -300l298 300h-198v900h-200v-900h-198zM800 400v100h200v-500h-100v400h-100zM800 800v400h300v-500h-100v100h-200zM901 900h100v200h-100v-200z" />
+<glyph unicode="&#xe155;" d="M2 300l298 -300l298 300h-198v900h-200v-900h-198zM700 100v200h500v-200h-500zM700 400v200h400v-200h-400zM700 700v200h300v-200h-300zM700 1000v200h200v-200h-200z" />
+<glyph unicode="&#xe156;" d="M2 300l298 -300l298 300h-198v900h-200v-900h-198zM700 100v200h200v-200h-200zM700 400v200h300v-200h-300zM700 700v200h400v-200h-400zM700 1000v200h500v-200h-500z" />
+<glyph unicode="&#xe157;" d="M0 400v300q0 165 117.5 282.5t282.5 117.5h300q162 0 281 -118.5t119 -281.5v-300q0 -165 -118.5 -282.5t-281.5 -117.5h-300q-165 0 -282.5 117.5t-117.5 282.5zM200 300q0 -41 29.5 -70.5t70.5 -29.5h500q41 0 70.5 29.5t29.5 70.5v500q0 41 -29.5 70.5t-70.5 29.5 h-500q-41 0 -70.5 -29.5t-29.5 -70.5v-500z" />
+<glyph unicode="&#xe158;" d="M0 400v300q0 163 119 281.5t281 118.5h300q165 0 282.5 -117.5t117.5 -282.5v-300q0 -165 -117.5 -282.5t-282.5 -117.5h-300q-163 0 -281.5 117.5t-118.5 282.5zM200 300q0 -41 29.5 -70.5t70.5 -29.5h500q41 0 70.5 29.5t29.5 70.5v500q0 41 -29.5 70.5t-70.5 29.5 h-500q-41 0 -70.5 -29.5t-29.5 -70.5v-500zM400 300l333 250l-333 250v-500z" />
+<glyph unicode="&#xe159;" d="M0 400v300q0 163 117.5 281.5t282.5 118.5h300q163 0 281.5 -119t118.5 -281v-300q0 -165 -117.5 -282.5t-282.5 -117.5h-300q-165 0 -282.5 117.5t-117.5 282.5zM200 300q0 -41 29.5 -70.5t70.5 -29.5h500q41 0 70.5 29.5t29.5 70.5v500q0 41 -29.5 70.5t-70.5 29.5 h-500q-41 0 -70.5 -29.5t-29.5 -70.5v-500zM300 700l250 -333l250 333h-500z" />
+<glyph unicode="&#xe160;" d="M0 400v300q0 165 117.5 282.5t282.5 117.5h300q165 0 282.5 -117.5t117.5 -282.5v-300q0 -162 -118.5 -281t-281.5 -119h-300q-165 0 -282.5 118.5t-117.5 281.5zM200 300q0 -41 29.5 -70.5t70.5 -29.5h500q41 0 70.5 29.5t29.5 70.5v500q0 41 -29.5 70.5t-70.5 29.5 h-500q-41 0 -70.5 -29.5t-29.5 -70.5v-500zM300 400h500l-250 333z" />
+<glyph unicode="&#xe161;" d="M0 400v300h300v200l400 -350l-400 -350v200h-300zM500 0v200h500q41 0 70.5 29.5t29.5 70.5v500q0 41 -29.5 70.5t-70.5 29.5h-500v200h400q165 0 282.5 -117.5t117.5 -282.5v-300q0 -165 -117.5 -282.5t-282.5 -117.5h-400z" />
+<glyph unicode="&#xe162;" d="M216 519q10 -19 32 -19h302q-155 -438 -160 -458q-5 -21 4 -32l9 -8l9 -1q13 0 26 16l538 630q15 19 6 36q-8 18 -32 16h-300q1 4 78 219.5t79 227.5q2 17 -6 27l-8 8h-9q-16 0 -25 -15q-4 -5 -98.5 -111.5t-228 -257t-209.5 -238.5q-17 -19 -7 -40z" />
+<glyph unicode="&#xe163;" d="M0 400q0 -165 117.5 -282.5t282.5 -117.5h300q47 0 100 15v185h-500q-41 0 -70.5 29.5t-29.5 70.5v500q0 41 29.5 70.5t70.5 29.5h500v185q-14 4 -114 7.5t-193 5.5l-93 2q-165 0 -282.5 -117.5t-117.5 -282.5v-300zM600 400v300h300v200l400 -350l-400 -350v200h-300z " />
+<glyph unicode="&#xe164;" d="M0 400q0 -165 117.5 -282.5t282.5 -117.5h300q163 0 281.5 117.5t118.5 282.5v98l-78 73l-122 -123v-148q0 -41 -29.5 -70.5t-70.5 -29.5h-500q-41 0 -70.5 29.5t-29.5 70.5v500q0 41 29.5 70.5t70.5 29.5h156l118 122l-74 78h-100q-165 0 -282.5 -117.5t-117.5 -282.5 v-300zM496 709l353 342l-149 149h500v-500l-149 149l-342 -353z" />
+<glyph unicode="&#xe165;" d="M4 600q0 162 80 299t217 217t299 80t299 -80t217 -217t80 -299t-80 -299t-217 -217t-299 -80t-299 80t-217 217t-80 299zM186 600q0 -171 121.5 -292.5t292.5 -121.5t292.5 121.5t121.5 292.5t-121.5 292.5t-292.5 121.5t-292.5 -121.5t-121.5 -292.5zM406 600 q0 80 57 137t137 57t137 -57t57 -137t-57 -137t-137 -57t-137 57t-57 137z" />
+<glyph unicode="&#xe166;" d="M0 0v275q0 11 7 18t18 7h1048q11 0 19 -7.5t8 -17.5v-275h-1100zM100 800l445 -500l450 500h-295v400h-300v-400h-300zM900 150h100v50h-100v-50z" />
+<glyph unicode="&#xe167;" d="M0 0v275q0 11 7 18t18 7h1048q11 0 19 -7.5t8 -17.5v-275h-1100zM100 700h300v-300h300v300h295l-445 500zM900 150h100v50h-100v-50z" />
+<glyph unicode="&#xe168;" d="M0 0v275q0 11 7 18t18 7h1048q11 0 19 -7.5t8 -17.5v-275h-1100zM100 705l305 -305l596 596l-154 155l-442 -442l-150 151zM900 150h100v50h-100v-50z" />
+<glyph unicode="&#xe169;" d="M0 0v275q0 11 7 18t18 7h1048q11 0 19 -7.5t8 -17.5v-275h-1100zM100 988l97 -98l212 213l-97 97zM200 401h700v699l-250 -239l-149 149l-212 -212l149 -149zM900 150h100v50h-100v-50z" />
+<glyph unicode="&#xe170;" d="M0 0v275q0 11 7 18t18 7h1048q11 0 19 -7.5t8 -17.5v-275h-1100zM200 612l212 -212l98 97l-213 212zM300 1200l239 -250l-149 -149l212 -212l149 148l248 -237v700h-699zM900 150h100v50h-100v-50z" />
+<glyph unicode="&#xe171;" d="M23 415l1177 784v-1079l-475 272l-310 -393v416h-392zM494 210l672 938l-672 -712v-226z" />
+<glyph unicode="&#xe172;" d="M0 150v1000q0 20 14.5 35t35.5 15h250v-300h500v300h100l200 -200v-850q0 -21 -15 -35.5t-35 -14.5h-150v400h-700v-400h-150q-21 0 -35.5 14.5t-14.5 35.5zM600 1000h100v200h-100v-200z" />
+<glyph unicode="&#xe173;" d="M0 150v1000q0 20 14.5 35t35.5 15h250v-300h500v300h100l200 -200v-218l-276 -275l-120 120l-126 -127h-378v-400h-150q-21 0 -35.5 14.5t-14.5 35.5zM581 306l123 123l120 -120l353 352l123 -123l-475 -476zM600 1000h100v200h-100v-200z" />
+<glyph unicode="&#xe174;" d="M0 150v1000q0 20 14.5 35t35.5 15h250v-300h500v300h100l200 -200v-269l-103 -103l-170 170l-298 -298h-329v-400h-150q-21 0 -35.5 14.5t-14.5 35.5zM600 1000h100v200h-100v-200zM700 133l170 170l-170 170l127 127l170 -170l170 170l127 -128l-170 -169l170 -170 l-127 -127l-170 170l-170 -170z" />
+<glyph unicode="&#xe175;" d="M0 150v1000q0 20 14.5 35t35.5 15h250v-300h500v300h100l200 -200v-300h-400v-200h-500v-400h-150q-21 0 -35.5 14.5t-14.5 35.5zM600 300l300 -300l300 300h-200v300h-200v-300h-200zM600 1000v200h100v-200h-100z" />
+<glyph unicode="&#xe176;" d="M0 150v1000q0 20 14.5 35t35.5 15h250v-300h500v300h100l200 -200v-402l-200 200l-298 -298h-402v-400h-150q-21 0 -35.5 14.5t-14.5 35.5zM600 300h200v-300h200v300h200l-300 300zM600 1000v200h100v-200h-100z" />
+<glyph unicode="&#xe177;" d="M0 250q0 -21 14.5 -35.5t35.5 -14.5h1100q21 0 35.5 14.5t14.5 35.5v550h-1200v-550zM0 900h1200v150q0 21 -14.5 35.5t-35.5 14.5h-1100q-21 0 -35.5 -14.5t-14.5 -35.5v-150zM100 300v200h400v-200h-400z" />
+<glyph unicode="&#xe178;" d="M0 400l300 298v-198h400v-200h-400v-198zM100 800v200h100v-200h-100zM300 800v200h100v-200h-100zM500 800v200h400v198l300 -298l-300 -298v198h-400zM800 300v200h100v-200h-100zM1000 300h100v200h-100v-200z" />
+<glyph unicode="&#xe179;" d="M100 700v400l50 100l50 -100v-300h100v300l50 100l50 -100v-300h100v300l50 100l50 -100v-400l-100 -203v-447q0 -21 -14.5 -35.5t-35.5 -14.5h-200q-21 0 -35.5 14.5t-14.5 35.5v447zM800 597q0 -29 10.5 -55.5t25 -43t29 -28.5t25.5 -18l10 -5v-397q0 -21 14.5 -35.5 t35.5 -14.5h200q21 0 35.5 14.5t14.5 35.5v1106q0 31 -18 40.5t-44 -7.5l-276 -117q-25 -16 -43.5 -50.5t-18.5 -65.5v-359z" />
+<glyph unicode="&#xe180;" d="M100 0h400v56q-75 0 -87.5 6t-12.5 44v394h500v-394q0 -38 -12.5 -44t-87.5 -6v-56h400v56q-4 0 -11 0.5t-24 3t-30 7t-24 15t-11 24.5v888q0 22 25 34.5t50 13.5l25 2v56h-400v-56q75 0 87.5 -6t12.5 -44v-394h-500v394q0 38 12.5 44t87.5 6v56h-400v-56q4 0 11 -0.5 t24 -3t30 -7t24 -15t11 -24.5v-888q0 -22 -25 -34.5t-50 -13.5l-25 -2v-56z" />
+<glyph unicode="&#xe181;" d="M0 300q0 -41 29.5 -70.5t70.5 -29.5h300q41 0 70.5 29.5t29.5 70.5v500q0 41 -29.5 70.5t-70.5 29.5h-300q-41 0 -70.5 -29.5t-29.5 -70.5v-500zM100 100h400l200 200h105l295 98v-298h-425l-100 -100h-375zM100 300v200h300v-200h-300zM100 600v200h300v-200h-300z M100 1000h400l200 -200v-98l295 98h105v200h-425l-100 100h-375zM700 402v163l400 133v-163z" />
+<glyph unicode="&#xe182;" d="M16.5 974.5q0.5 -21.5 16 -90t46.5 -140t104 -177.5t175 -208q103 -103 207.5 -176t180 -103.5t137 -47t92.5 -16.5l31 1l163 162q16 17 13 40.5t-22 37.5l-192 136q-19 14 -45 12t-42 -19l-119 -118q-143 103 -267 227q-126 126 -227 268l118 118q17 17 20 41.5 t-11 44.5l-139 194q-14 19 -36.5 22t-40.5 -14l-162 -162q-1 -11 -0.5 -32.5z" />
+<glyph unicode="&#xe183;" d="M0 50v212q0 20 10.5 45.5t24.5 39.5l365 303v50q0 4 1 10.5t12 22.5t30 28.5t60 23t97 10.5t97 -10t60 -23.5t30 -27.5t12 -24l1 -10v-50l365 -303q14 -14 24.5 -39.5t10.5 -45.5v-212q0 -21 -15 -35.5t-35 -14.5h-1100q-21 0 -35.5 14.5t-14.5 35.5zM0 712 q0 -21 14.5 -33.5t34.5 -8.5l202 33q20 4 34.5 21t14.5 38v146q141 24 300 24t300 -24v-146q0 -21 14.5 -38t34.5 -21l202 -33q20 -4 34.5 8.5t14.5 33.5v200q-6 8 -19 20.5t-63 45t-112 57t-171 45t-235 20.5q-92 0 -175 -10.5t-141.5 -27t-108.5 -36.5t-81.5 -40 t-53.5 -36.5t-31 -27.5l-9 -10v-200z" />
+<glyph unicode="&#xe184;" d="M100 0v100h1100v-100h-1100zM175 200h950l-125 150v250l100 100v400h-100v-200h-100v200h-200v-200h-100v200h-200v-200h-100v200h-100v-400l100 -100v-250z" />
+<glyph unicode="&#xe185;" d="M100 0h300v400q0 41 -29.5 70.5t-70.5 29.5h-100q-41 0 -70.5 -29.5t-29.5 -70.5v-400zM500 0v1000q0 41 29.5 70.5t70.5 29.5h100q41 0 70.5 -29.5t29.5 -70.5v-1000h-300zM900 0v700q0 41 29.5 70.5t70.5 29.5h100q41 0 70.5 -29.5t29.5 -70.5v-700h-300z" />
+<glyph unicode="&#xe186;" d="M-100 300v500q0 124 88 212t212 88h700q124 0 212 -88t88 -212v-500q0 -124 -88 -212t-212 -88h-700q-124 0 -212 88t-88 212zM100 200h900v700h-900v-700zM200 300h300v300h-200v100h200v100h-300v-300h200v-100h-200v-100zM600 300h200v100h100v300h-100v100h-200v-500 zM700 400v300h100v-300h-100z" />
+<glyph unicode="&#xe187;" d="M-100 300v500q0 124 88 212t212 88h700q124 0 212 -88t88 -212v-500q0 -124 -88 -212t-212 -88h-700q-124 0 -212 88t-88 212zM100 200h900v700h-900v-700zM200 300h100v200h100v-200h100v500h-100v-200h-100v200h-100v-500zM600 300h200v100h100v300h-100v100h-200v-500 zM700 400v300h100v-300h-100z" />
+<glyph unicode="&#xe188;" d="M-100 300v500q0 124 88 212t212 88h700q124 0 212 -88t88 -212v-500q0 -124 -88 -212t-212 -88h-700q-124 0 -212 88t-88 212zM100 200h900v700h-900v-700zM200 300h300v100h-200v300h200v100h-300v-500zM600 300h300v100h-200v300h200v100h-300v-500z" />
+<glyph unicode="&#xe189;" d="M-100 300v500q0 124 88 212t212 88h700q124 0 212 -88t88 -212v-500q0 -124 -88 -212t-212 -88h-700q-124 0 -212 88t-88 212zM100 200h900v700h-900v-700zM200 550l300 -150v300zM600 400l300 150l-300 150v-300z" />
+<glyph unicode="&#xe190;" d="M-100 300v500q0 124 88 212t212 88h700q124 0 212 -88t88 -212v-500q0 -124 -88 -212t-212 -88h-700q-124 0 -212 88t-88 212zM100 200h900v700h-900v-700zM200 300v500h700v-500h-700zM300 400h130q41 0 68 42t27 107t-28.5 108t-66.5 43h-130v-300zM575 549 q0 -65 27 -107t68 -42h130v300h-130q-38 0 -66.5 -43t-28.5 -108z" />
+<glyph unicode="&#xe191;" d="M-100 300v500q0 124 88 212t212 88h700q124 0 212 -88t88 -212v-500q0 -124 -88 -212t-212 -88h-700q-124 0 -212 88t-88 212zM100 200h900v700h-900v-700zM200 300h300v300h-200v100h200v100h-300v-300h200v-100h-200v-100zM601 300h100v100h-100v-100zM700 700h100 v-400h100v500h-200v-100z" />
+<glyph unicode="&#xe192;" d="M-100 300v500q0 124 88 212t212 88h700q124 0 212 -88t88 -212v-500q0 -124 -88 -212t-212 -88h-700q-124 0 -212 88t-88 212zM100 200h900v700h-900v-700zM200 300h300v400h-200v100h-100v-500zM301 400v200h100v-200h-100zM601 300h100v100h-100v-100zM700 700h100 v-400h100v500h-200v-100z" />
+<glyph unicode="&#xe193;" d="M-100 300v500q0 124 88 212t212 88h700q124 0 212 -88t88 -212v-500q0 -124 -88 -212t-212 -88h-700q-124 0 -212 88t-88 212zM100 200h900v700h-900v-700zM200 700v100h300v-300h-99v-100h-100v100h99v200h-200zM201 300v100h100v-100h-100zM601 300v100h100v-100h-100z M700 700v100h200v-500h-100v400h-100z" />
+<glyph unicode="&#xe194;" d="M4 600q0 162 80 299t217 217t299 80t299 -80t217 -217t80 -299t-80 -299t-217 -217t-299 -80t-299 80t-217 217t-80 299zM186 600q0 -171 121.5 -292.5t292.5 -121.5t292.5 121.5t121.5 292.5t-121.5 292.5t-292.5 121.5t-292.5 -121.5t-121.5 -292.5zM400 500v200 l100 100h300v-100h-300v-200h300v-100h-300z" />
+<glyph unicode="&#xe195;" d="M0 600q0 162 80 299t217 217t299 80t299 -80t217 -217t80 -299t-80 -299t-217 -217t-299 -80t-299 80t-217 217t-80 299zM182 600q0 -171 121.5 -292.5t292.5 -121.5t292.5 121.5t121.5 292.5t-121.5 292.5t-292.5 121.5t-292.5 -121.5t-121.5 -292.5zM400 400v400h300 l100 -100v-100h-100v100h-200v-100h200v-100h-200v-100h-100zM700 400v100h100v-100h-100z" />
+<glyph unicode="&#xe197;" d="M-14 494q0 -80 56.5 -137t135.5 -57h222v300h400v-300h128q120 0 205 86t85 208q0 120 -85 206.5t-205 86.5q-46 0 -90 -14q-44 97 -134.5 156.5t-200.5 59.5q-152 0 -260 -107.5t-108 -260.5q0 -25 2 -37q-66 -14 -108.5 -67.5t-42.5 -122.5zM300 200h200v300h200v-300 h200l-300 -300z" />
+<glyph unicode="&#xe198;" d="M-14 494q0 -80 56.5 -137t135.5 -57h8l414 414l403 -403q94 26 154.5 104t60.5 178q0 121 -85 207.5t-205 86.5q-46 0 -90 -14q-44 97 -134.5 156.5t-200.5 59.5q-152 0 -260 -107.5t-108 -260.5q0 -25 2 -37q-66 -14 -108.5 -67.5t-42.5 -122.5zM300 200l300 300 l300 -300h-200v-300h-200v300h-200z" />
+<glyph unicode="&#xe199;" d="M100 200h400v-155l-75 -45h350l-75 45v155h400l-270 300h170l-270 300h170l-300 333l-300 -333h170l-270 -300h170z" />
+<glyph unicode="&#xe200;" d="M121 700q0 -53 28.5 -97t75.5 -65q-4 -16 -4 -38q0 -74 52.5 -126.5t126.5 -52.5q56 0 100 30v-306l-75 -45h350l-75 45v306q46 -30 100 -30q74 0 126.5 52.5t52.5 126.5q0 24 -9 55q50 32 79.5 83t29.5 112q0 90 -61.5 155.5t-150.5 71.5q-26 89 -99.5 145.5 t-167.5 56.5q-116 0 -197.5 -81.5t-81.5 -197.5q0 -4 1 -12t1 -11q-14 2 -23 2q-74 0 -126.5 -52.5t-52.5 -126.5z" />
+</font>
+</defs></svg> 
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/ambari/blob/5eb22214/contrib/views/pig/src/main/resources/ui/pig-web/app/assets/index.html
----------------------------------------------------------------------
diff --git a/contrib/views/pig/src/main/resources/ui/pig-web/app/assets/index.html b/contrib/views/pig/src/main/resources/ui/pig-web/app/assets/index.html
new file mode 100644
index 0000000..7f87394
--- /dev/null
+++ b/contrib/views/pig/src/main/resources/ui/pig-web/app/assets/index.html
@@ -0,0 +1,29 @@
+<!--
+   Licensed to the Apache Software Foundation (ASF) under one or more
+   contributor license agreements.  See the NOTICE file distributed with
+   this work for additional information regarding copyright ownership.
+   The ASF licenses this file to You under the Apache License, Version 2.0
+   (the "License"); you may not use this file except in compliance with
+   the License.  You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.
+-->
+
+<!DOCTYPE html>
+<html>
+  <head>
+    <meta charset="utf-8">
+    <title>Pig</title>
+    <link rel="stylesheet" href="static/stylesheets/app.css">
+    <script src="static/javascripts/vendor.js"></script>
+    <script src="static/javascripts/app.js"></script>
+    <script>require('initialize');</script>
+  </head>
+  <body></body>
+</html>


[7/7] git commit: AMBARI-5616 - Ambari Views: Pig view (Roman Rader via tbeerbower)

Posted by tb...@apache.org.
AMBARI-5616 - Ambari Views: Pig view (Roman Rader via tbeerbower)


Project: http://git-wip-us.apache.org/repos/asf/ambari/repo
Commit: http://git-wip-us.apache.org/repos/asf/ambari/commit/5eb22214
Tree: http://git-wip-us.apache.org/repos/asf/ambari/tree/5eb22214
Diff: http://git-wip-us.apache.org/repos/asf/ambari/diff/5eb22214

Branch: refs/heads/trunk
Commit: 5eb22214397b55a153594faa75705517f55d945c
Parents: 75505c6
Author: tbeerbower <tb...@hortonworks.com>
Authored: Fri May 2 12:22:07 2014 -0400
Committer: tbeerbower <tb...@hortonworks.com>
Committed: Fri May 2 12:24:30 2014 -0400

----------------------------------------------------------------------
 contrib/views/pig/pom.xml                       | 198 +++++++++
 .../ambari/view/pig/PigServiceRouter.java       |  48 +++
 .../persistence/InstanceKeyValueStorage.java    | 107 +++++
 .../view/pig/persistence/KeyValueStorage.java   | 154 +++++++
 .../pig/persistence/LocalKeyValueStorage.java   |  61 +++
 .../persistence/PersistentConfiguration.java    |  42 ++
 .../ambari/view/pig/persistence/Storage.java    |  39 ++
 .../utils/ContextConfigurationAdapter.java      | 250 +++++++++++
 .../persistence/utils/FilteringStrategy.java    |  23 ++
 .../view/pig/persistence/utils/Indexed.java     |  24 ++
 .../pig/persistence/utils/ItemNotFound.java     |  22 +
 .../utils/OnlyOwnersFilteringStrategy.java      |  33 ++
 .../view/pig/persistence/utils/Owned.java       |  24 ++
 .../pig/persistence/utils/PersonalResource.java |  22 +
 .../view/pig/persistence/utils/StorageUtil.java |  53 +++
 .../view/pig/resources/CRUDResourceManager.java |  91 ++++
 .../resources/PersonalCRUDResourceManager.java  |  81 ++++
 .../resources/SharedCRUDResourceManager.java    |  45 ++
 .../view/pig/resources/files/FileResource.java  |  27 ++
 .../view/pig/resources/files/FileService.java   | 141 +++++++
 .../pig/resources/jobs/JobResourceManager.java  | 280 +++++++++++++
 .../pig/resources/jobs/JobResourceProvider.java | 100 +++++
 .../view/pig/resources/jobs/JobService.java     | 243 +++++++++++
 .../view/pig/resources/jobs/models/PigJob.java  | 253 ++++++++++++
 .../pig/resources/jobs/utils/JobPolling.java    | 143 +++++++
 .../scripts/ScriptResourceManager.java          | 101 +++++
 .../scripts/ScriptResourceProvider.java         | 103 +++++
 .../pig/resources/scripts/ScriptService.java    | 154 +++++++
 .../pig/resources/scripts/models/PigScript.java | 131 ++++++
 .../pig/resources/udf/UDFResourceManager.java   |  34 ++
 .../pig/resources/udf/UDFResourceProvider.java  | 105 +++++
 .../view/pig/resources/udf/UDFService.java      | 156 +++++++
 .../view/pig/resources/udf/models/UDF.java      |  79 ++++
 .../ambari/view/pig/services/BaseService.java   | 117 ++++++
 .../ambari/view/pig/services/HelpService.java   |  56 +++
 .../view/pig/templeton/client/Request.java      | 213 ++++++++++
 .../view/pig/templeton/client/TempletonApi.java | 164 ++++++++
 .../pig/templeton/client/TempletonRequest.java  |  80 ++++
 .../ambari/view/pig/utils/FilePaginator.java    |  83 ++++
 .../apache/ambari/view/pig/utils/HdfsApi.java   | 189 +++++++++
 .../src/main/resources/ui/pig-web/.gitignore    |  34 ++
 .../pig/src/main/resources/ui/pig-web/README.md |  15 +
 .../src/main/resources/ui/pig-web/app/app.js    |  23 ++
 .../fonts/glyphicons-halflings-regular.svg      | 229 +++++++++++
 .../resources/ui/pig-web/app/assets/index.html  |  29 ++
 .../fonts/glyphicons-halflings-regular.svg      | 229 +++++++++++
 .../ui/pig-web/app/controllers/edit.js          | 165 ++++++++
 .../ui/pig-web/app/controllers/jobResults.js    |  58 +++
 .../pig-web/app/controllers/modal/pigModal.js   |  22 +
 .../resources/ui/pig-web/app/controllers/pig.js |  26 ++
 .../ui/pig-web/app/controllers/pigHistory.js    |  28 ++
 .../ui/pig-web/app/controllers/pigJob.js        |  31 ++
 .../ui/pig-web/app/controllers/pigScriptEdit.js |  61 +++
 .../app/controllers/pigScriptEditResults.js     |  22 +
 .../ui/pig-web/app/controllers/pigScriptList.js |  23 ++
 .../ui/pig-web/app/controllers/pigUdfs.js       |  23 ++
 .../ui/pig-web/app/controllers/poll.js          |  56 +++
 .../app/controllers/util/pigUtilAlert.js        |  28 ++
 .../main/resources/ui/pig-web/app/initialize.js | 157 +++++++
 .../resources/ui/pig-web/app/models/file.js     |  26 ++
 .../resources/ui/pig-web/app/models/pig_job.js  |  90 ++++
 .../ui/pig-web/app/models/pig_script.js         |  43 ++
 .../main/resources/ui/pig-web/app/models/udf.js |  25 ++
 .../src/main/resources/ui/pig-web/app/router.js |  37 ++
 .../ui/pig-web/app/routes/jobResults.js         |  29 ++
 .../main/resources/ui/pig-web/app/routes/pig.js |  69 ++++
 .../ui/pig-web/app/routes/pigHistory.js         |  28 ++
 .../resources/ui/pig-web/app/routes/pigIndex.js |  25 ++
 .../resources/ui/pig-web/app/routes/pigJob.js   |  54 +++
 .../ui/pig-web/app/routes/pigScriptEdit.js      |  71 ++++
 .../ui/pig-web/app/routes/pigScriptEditIndex.js |  27 ++
 .../pig-web/app/routes/pigScriptEditResults.js  |  36 ++
 .../ui/pig-web/app/routes/pigScriptList.js      |  88 ++++
 .../resources/ui/pig-web/app/routes/pigUdfs.js  |  55 +++
 .../resources/ui/pig-web/app/styles/style.less  | 295 +++++++++++++
 .../ui/pig-web/app/templates/application.hbs    |  21 +
 .../ui/pig-web/app/templates/index.hbs          |  18 +
 .../ui/pig-web/app/templates/loading.hbs        |  19 +
 .../resources/ui/pig-web/app/templates/pig.hbs  |  31 ++
 .../ui/pig-web/app/templates/pig/history.hbs    |  46 +++
 .../ui/pig-web/app/templates/pig/index.hbs      |  19 +
 .../ui/pig-web/app/templates/pig/job.hbs        |  39 ++
 .../ui/pig-web/app/templates/pig/jobEdit.hbs    |  18 +
 .../ui/pig-web/app/templates/pig/jobResults.hbs |  19 +
 .../app/templates/pig/jobResultsOutput.hbs      |  40 ++
 .../ui/pig-web/app/templates/pig/jobStatus.hbs  |  18 +
 .../ui/pig-web/app/templates/pig/loading.hbs    |  20 +
 .../app/templates/pig/modal/confirmdelete.hbs   |  29 ++
 .../app/templates/pig/modal/createScript.hbs    |  37 ++
 .../app/templates/pig/modal/createUdf.hbs       |  36 ++
 .../app/templates/pig/modal/modalLayout.hbs     |  25 ++
 .../ui/pig-web/app/templates/pig/scriptEdit.hbs | 120 ++++++
 .../app/templates/pig/scriptEditIndex.hbs       |  18 +
 .../ui/pig-web/app/templates/pig/scriptList.hbs |  57 +++
 .../pig-web/app/templates/pig/scriptResults.hbs |  18 +
 .../app/templates/pig/scriptResultsNav.hbs      |  19 +
 .../ui/pig-web/app/templates/pig/udfs.hbs       |  45 ++
 .../app/templates/pig/util/alert-content.hbs    |  22 +
 .../ui/pig-web/app/templates/pig/util/alert.hbs |  21 +
 .../app/templates/pig/util/pigHelper.hbs        |  34 ++
 .../app/templates/pig/util/script-nav.hbs       |  30 ++
 .../resources/ui/pig-web/app/translations.js    | 110 +++++
 .../main/resources/ui/pig-web/app/views/pig.js  |  59 +++
 .../ui/pig-web/app/views/pig/jobResults.js      |  52 +++
 .../app/views/pig/modal/confirmDelete.js        |  29 ++
 .../pig-web/app/views/pig/modal/createScript.js |  34 ++
 .../ui/pig-web/app/views/pig/modal/createUdf.js |  38 ++
 .../ui/pig-web/app/views/pig/modal/pigModal.js  |  35 ++
 .../ui/pig-web/app/views/pig/pigHistory.js      |  36 ++
 .../ui/pig-web/app/views/pig/pigJob.js          |  41 ++
 .../ui/pig-web/app/views/pig/pigUdfs.js         |  23 ++
 .../ui/pig-web/app/views/pig/scriptEdit.js      | 257 ++++++++++++
 .../ui/pig-web/app/views/pig/scriptList.js      |  22 +
 .../ui/pig-web/app/views/pig/scriptResults.js   |  23 ++
 .../pig-web/app/views/pig/scriptResultsNav.js   |  49 +++
 .../pig-web/app/views/pig/util/pigUtilAlert.js  |  55 +++
 .../views/pig/src/main/resources/ui/pig-web/bin |   1 +
 .../src/main/resources/ui/pig-web/bower.json    |  22 +
 .../src/main/resources/ui/pig-web/config.coffee |  51 +++
 .../generators/collection/collection.js.hbs     |  23 ++
 .../generators/collection/generator.json        |   9 +
 .../generators/controller/controller.js.hbs     |  23 ++
 .../generators/controller/generator.json        |   9 +
 .../ui/pig-web/generators/model/generator.json  |   9 +
 .../ui/pig-web/generators/model/model.js.hbs    |  23 ++
 .../ui/pig-web/generators/route/generator.json  |   9 +
 .../ui/pig-web/generators/route/route.js.hbs    |  25 ++
 .../pig-web/generators/template/generator.json  |   9 +
 .../generators/template/template.hbs.hbs        |  18 +
 .../ui/pig-web/generators/view/generator.json   |   9 +
 .../ui/pig-web/generators/view/view.js.hbs      |  23 ++
 .../src/main/resources/ui/pig-web/package.json  |  22 +
 .../main/resources/ui/pig-web/test/spec.coffee  |  17 +
 .../main/resources/ui/pig-web/vendor/emacs.js   |  50 +++
 contrib/views/pig/src/main/resources/view.xml   | 140 +++++++
 .../org/apache/ambari/view/pig/BasePigTest.java |  96 +++++
 .../org/apache/ambari/view/pig/HDFSTest.java    |  60 +++
 .../apache/ambari/view/pig/test/FileTest.java   | 203 +++++++++
 .../apache/ambari/view/pig/test/HelpTest.java   |  59 +++
 .../apache/ambari/view/pig/test/JobTest.java    | 410 +++++++++++++++++++
 .../apache/ambari/view/pig/test/ScriptTest.java | 175 ++++++++
 .../view/pig/test/ScriptTestHDFSUnmanaged.java  | 109 +++++
 .../view/pig/test/ScriptTestUnmanaged.java      |  92 +++++
 .../apache/ambari/view/pig/test/UDFTest.java    | 116 ++++++
 contrib/views/pom.xml                           | 133 ++++++
 145 files changed, 10153 insertions(+)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/ambari/blob/5eb22214/contrib/views/pig/pom.xml
----------------------------------------------------------------------
diff --git a/contrib/views/pig/pom.xml b/contrib/views/pig/pom.xml
new file mode 100644
index 0000000..3dd71a7
--- /dev/null
+++ b/contrib/views/pig/pom.xml
@@ -0,0 +1,198 @@
+<!--
+   Licensed to the Apache Software Foundation (ASF) under one or more
+   contributor license agreements.  See the NOTICE file distributed with
+   this work for additional information regarding copyright ownership.
+   The ASF licenses this file to You under the Apache License, Version 2.0
+   (the "License"); you may not use this file except in compliance with
+   the License.  You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.
+-->
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+  <modelVersion>4.0.0</modelVersion>
+  <groupId>org.apache.ambari.view</groupId>
+  <artifactId>pig</artifactId>
+  <version>0.0.1-SNAPSHOT</version>
+  <name>Pig</name>
+
+  <parent>
+    <groupId>org.apache.ambari.views</groupId>
+    <artifactId>ambari-views-poc</artifactId>
+    <version>0.1.0-SNAPSHOT</version>
+  </parent>
+
+  <dependencies>
+    <dependency>
+      <groupId>com.google.inject</groupId>
+      <artifactId>guice</artifactId>
+    </dependency>
+    <dependency>
+      <groupId>com.sun.jersey.contribs</groupId>
+      <artifactId>jersey-multipart</artifactId>
+      <version>1.18</version>
+    </dependency>
+    <dependency>
+      <groupId>com.sun.jersey</groupId>
+      <artifactId>jersey-client</artifactId>
+      <version>1.8</version>
+    </dependency>
+    <dependency>
+      <groupId>com.sun.jersey</groupId>
+      <artifactId>jersey-core</artifactId>
+      <version>1.18.1</version>
+    </dependency>
+    <dependency>
+      <groupId>com.sun.jersey</groupId>
+      <artifactId>jersey-json</artifactId>
+      <version>1.9</version>
+    </dependency>
+    <dependency>
+      <groupId>com.googlecode.json-simple</groupId>
+      <artifactId>json-simple</artifactId>
+    </dependency>
+    <dependency>
+      <groupId>commons-configuration</groupId>
+      <artifactId>commons-configuration</artifactId>
+      <version>1.6</version>
+    </dependency>
+    <dependency>
+      <groupId>org.apache.ambari</groupId>
+      <artifactId>ambari-views</artifactId>
+      <scope>provided</scope>
+    </dependency>
+    <dependency>
+      <groupId>com.google.code.gson</groupId>
+      <artifactId>gson</artifactId>
+      <version>2.2.2</version>
+    </dependency>
+    <dependency>
+      <groupId>javax.servlet</groupId>
+      <artifactId>javax.servlet-api</artifactId>
+      <version>3.0.1</version>
+    </dependency>
+    <dependency>
+      <groupId>org.slf4j</groupId>
+      <artifactId>slf4j-api</artifactId>
+      <version>1.7.5</version>
+    </dependency>
+    <dependency>
+      <groupId>org.apache.hadoop</groupId>
+      <artifactId>hadoop-hdfs</artifactId>
+      <version>${hadoop-version}</version>
+    </dependency>
+    <dependency>
+      <groupId>org.apache.hadoop</groupId>
+      <artifactId>hadoop-common</artifactId>
+      <version>${hadoop-version}</version>
+    </dependency>
+    <dependency>
+      <groupId>javax.ws.rs</groupId>
+      <artifactId>javax.ws.rs-api</artifactId>
+      <version>2.0</version>
+    </dependency>
+    <dependency>
+      <groupId>junit</groupId>
+      <artifactId>junit</artifactId>
+      <scope>test</scope>
+    </dependency>
+    <dependency>
+      <groupId>org.easymock</groupId>
+      <artifactId>easymock</artifactId>
+      <scope>test</scope>
+    </dependency>
+    <dependency>
+      <groupId>org.apache.hadoop</groupId>
+      <artifactId>hadoop-minicluster</artifactId>
+      <version>${hadoop-version}</version>
+      <scope>test</scope>
+    </dependency>
+  </dependencies>
+
+  <properties>
+    <hadoop-version>2.2.0</hadoop-version>
+    <ambari.version>1.3.0-SNAPSHOT</ambari.version>
+  </properties>
+  <build>
+    <plugins>
+
+      <!-- Building frontend -->
+      <plugin>
+        <groupId>com.github.eirslett</groupId>
+        <artifactId>frontend-maven-plugin</artifactId>
+        <version>0.0.14</version>
+        <configuration>
+          <nodeVersion>v0.10.26</nodeVersion>
+          <npmVersion>1.4.3</npmVersion>
+          <workingDirectory>src/main/resources/ui/pig-web/</workingDirectory>
+        </configuration>
+        <executions>
+          <execution>
+            <id>install node and npm</id>
+            <phase>generate-sources</phase>
+            <goals>
+              <goal>install-node-and-npm</goal>
+            </goals>
+          </execution>
+          <execution>
+            <id>npm install</id>
+            <phase>generate-sources</phase>
+            <goals>
+              <goal>npm</goal>
+            </goals>
+            <configuration>
+              <arguments>install --unsafe-perm</arguments>
+            </configuration>
+          </execution>
+        </executions>
+      </plugin>
+
+      <plugin>
+        <artifactId>exec-maven-plugin</artifactId>
+        <groupId>org.codehaus.mojo</groupId>
+        <executions>
+          <execution>
+            <id>Brunch build</id>
+            <phase>generate-sources</phase>
+            <goals>
+              <goal>exec</goal>
+            </goals>
+            <configuration>
+              <workingDirectory>${basedir}/src/main/resources/ui/pig-web</workingDirectory>
+              <executable>node/node</executable>
+              <arguments>
+                <argument>node_modules/.bin/brunch</argument>
+                <argument>build</argument>
+                <argument>--production</argument>
+              </arguments>
+            </configuration>
+          </execution>
+        </executions>
+      </plugin>
+
+    </plugins>
+
+    <resources>
+      <resource>
+        <directory>src/main/resources</directory>
+        <filtering>false</filtering>
+        <includes>
+          <include>META-INF/**/*</include>
+          <include>view.xml</include>
+        </includes>
+      </resource>
+      <resource>
+        <directory>src/main/resources/ui/pig-web/public</directory>
+        <filtering>false</filtering>
+      </resource>
+    </resources>
+  </build>
+
+
+</project>

http://git-wip-us.apache.org/repos/asf/ambari/blob/5eb22214/contrib/views/pig/src/main/java/org/apache/ambari/view/pig/PigServiceRouter.java
----------------------------------------------------------------------
diff --git a/contrib/views/pig/src/main/java/org/apache/ambari/view/pig/PigServiceRouter.java b/contrib/views/pig/src/main/java/org/apache/ambari/view/pig/PigServiceRouter.java
new file mode 100644
index 0000000..e1098e7
--- /dev/null
+++ b/contrib/views/pig/src/main/java/org/apache/ambari/view/pig/PigServiceRouter.java
@@ -0,0 +1,48 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.ambari.view.pig;
+
+
+import com.google.inject.Inject;
+import org.apache.ambari.view.ViewContext;
+import org.apache.ambari.view.ViewResourceHandler;
+import org.apache.ambari.view.pig.persistence.Storage;
+import org.apache.ambari.view.pig.services.HelpService;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import javax.ws.rs.Path;
+
+public class PigServiceRouter {
+    @Inject
+    ViewContext context;
+
+    @Inject
+    protected ViewResourceHandler handler;
+
+    protected final static Logger LOG =
+            LoggerFactory.getLogger(PigServiceRouter.class);
+
+    private Storage storage = null;
+
+    @Path("/help")
+    public HelpService help(){
+        return new HelpService(context, handler);
+    }
+}

http://git-wip-us.apache.org/repos/asf/ambari/blob/5eb22214/contrib/views/pig/src/main/java/org/apache/ambari/view/pig/persistence/InstanceKeyValueStorage.java
----------------------------------------------------------------------
diff --git a/contrib/views/pig/src/main/java/org/apache/ambari/view/pig/persistence/InstanceKeyValueStorage.java b/contrib/views/pig/src/main/java/org/apache/ambari/view/pig/persistence/InstanceKeyValueStorage.java
new file mode 100644
index 0000000..101dcb9
--- /dev/null
+++ b/contrib/views/pig/src/main/java/org/apache/ambari/view/pig/persistence/InstanceKeyValueStorage.java
@@ -0,0 +1,107 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.ambari.view.pig.persistence;
+
+import org.apache.ambari.view.ViewContext;
+import org.apache.ambari.view.pig.persistence.utils.*;
+import org.apache.commons.configuration.Configuration;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+
+/**
+ * Persistent storage engine for storing java beans to
+ * properties file
+ * Path to file should be in 'dataworker.storagePath' parameter
+ */
+public class InstanceKeyValueStorage extends KeyValueStorage {
+    private final static Logger LOG =
+            LoggerFactory.getLogger(InstanceKeyValueStorage.class);
+
+    private ContextConfigurationAdapter config = null;
+    private int VALUE_LENGTH_LIMIT = 254;
+
+    public InstanceKeyValueStorage(ViewContext context) {
+        super(context);
+    }
+
+    @Override
+    protected synchronized Configuration getConfig() {
+        if (config == null) {
+            config = new ContextConfigurationAdapter(context);
+        }
+        return config;
+    }
+
+    /**
+     * Value is limited to 256 symbols, this code splits value into chunks and saves them as <key>#<chunk_id>
+     * @param modelPropName key
+     * @param json value
+     */
+    protected void write(String modelPropName, String json) {
+        int saved = 0;
+        int page = 1;
+        while (saved < json.length()) {
+            int end = Math.min(saved + VALUE_LENGTH_LIMIT, json.length());
+            String substring = json.substring(saved, end);
+            getConfig().setProperty(modelPropName + "#" + page, substring);
+            saved += VALUE_LENGTH_LIMIT;
+            page += 1;
+            LOG.debug("Chunk saved: " + modelPropName + "#" + page + "=" + substring);
+        }
+        getConfig().setProperty(modelPropName, page - 1);
+        LOG.debug("Write finished: " + modelPropName + " pages:" + (page - 1));
+    }
+
+    /**
+     * Read chunked value (keys format <key>#<chunk_id>)
+     * @param modelPropName key
+     * @return value
+     */
+    protected String read(String modelPropName) {
+        StringBuilder result = new StringBuilder();
+        int pages = getConfig().getInt(modelPropName);
+        LOG.debug("Read started: " + modelPropName + " pages:" + pages);
+
+        for(int page = 1; page <= pages; page++) {
+            String substring = getConfig().getString(modelPropName + "#" + page);
+            LOG.debug("Chunk read: " + modelPropName + "#" + page + "=" + substring);
+            if (substring != null) {
+                result.append(substring);
+            }
+        }
+
+        return result.toString();
+    }
+
+    /**
+     * Remove chunked value (keys format <key>#<chunk_id>)
+     * @param modelPropName key
+     */
+    protected void clear(String modelPropName) {
+        int pages = getConfig().getInt(modelPropName);
+        LOG.debug("Clean started: " + modelPropName + " pages:" + pages);
+
+        for(int page = 1; page <= pages; page++) {
+            getConfig().clearProperty(modelPropName + "#" + page);
+            LOG.debug("Chunk clean: " + modelPropName + "#" + page);
+        }
+        getConfig().clearProperty(modelPropName);
+    }
+}

http://git-wip-us.apache.org/repos/asf/ambari/blob/5eb22214/contrib/views/pig/src/main/java/org/apache/ambari/view/pig/persistence/KeyValueStorage.java
----------------------------------------------------------------------
diff --git a/contrib/views/pig/src/main/java/org/apache/ambari/view/pig/persistence/KeyValueStorage.java b/contrib/views/pig/src/main/java/org/apache/ambari/view/pig/persistence/KeyValueStorage.java
new file mode 100644
index 0000000..db18680
--- /dev/null
+++ b/contrib/views/pig/src/main/java/org/apache/ambari/view/pig/persistence/KeyValueStorage.java
@@ -0,0 +1,154 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.ambari.view.pig.persistence;
+
+import com.google.gson.Gson;
+import org.apache.ambari.view.ViewContext;
+import org.apache.ambari.view.pig.persistence.utils.FilteringStrategy;
+import org.apache.ambari.view.pig.persistence.utils.Indexed;
+import org.apache.ambari.view.pig.persistence.utils.ItemNotFound;
+import org.apache.ambari.view.pig.persistence.utils.OnlyOwnersFilteringStrategy;
+import org.apache.commons.configuration.Configuration;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * Engine storing objects to key-value storage
+ */
+public abstract class KeyValueStorage implements Storage {
+    private final static Logger LOG =
+            LoggerFactory.getLogger(KeyValueStorage.class);
+    protected final Gson gson = new Gson();
+    protected ViewContext context;
+
+    public KeyValueStorage(ViewContext context) {
+        this.context = context;
+    }
+
+    protected abstract Configuration getConfig();
+
+    @Override
+    public synchronized void store(Indexed obj) {
+        String modelIndexingPropName = getIndexPropertyName(obj.getClass());
+
+        if (obj.getId() == null) {
+            int lastIndex = getConfig().getInt(modelIndexingPropName, 0);
+            lastIndex ++;
+            getConfig().setProperty(modelIndexingPropName, lastIndex);
+            obj.setId(Integer.toString(lastIndex));
+        }
+
+        String modelPropName = getItemPropertyName(obj.getClass(), Integer.parseInt(obj.getId()));
+        String json = serialize(obj);
+        write(modelPropName, json);
+    }
+
+    @Override
+    public <T extends Indexed> T load(Class<T> model, int id) throws ItemNotFound {
+        String modelPropName = getItemPropertyName(model, id);
+        LOG.debug(String.format("Loading %s", modelPropName));
+        if (getConfig().containsKey(modelPropName)) {
+            String json = read(modelPropName);
+            LOG.debug(String.format("json: %s", json));
+            return deserialize(model, json);
+        } else {
+            throw new ItemNotFound();
+        }
+    }
+
+    /**
+     * Write json to storage
+     * @param modelPropName key
+     * @param json value
+     */
+    protected void write(String modelPropName, String json) {
+        getConfig().setProperty(modelPropName, json);
+    }
+
+    /**
+     * Read json from storage
+     * @param modelPropName key
+     * @return value
+     */
+    protected String read(String modelPropName) {
+        return getConfig().getString(modelPropName);
+    }
+
+    /**
+     * Remove line from storage
+     * @param modelPropName key
+     */
+    protected void clear(String modelPropName) {
+        getConfig().clearProperty(modelPropName);
+    }
+
+    protected String serialize(Indexed obj) {
+        return gson.toJson(obj);
+    }
+
+    protected <T extends Indexed> T deserialize(Class<T> model, String json) {
+        return gson.fromJson(json, model);
+    }
+
+    @Override
+    public synchronized <T extends Indexed> List<T> loadAll(Class<T> model, FilteringStrategy filter) {
+        ArrayList<T> list = new ArrayList<T>();
+        String modelIndexingPropName = getIndexPropertyName(model);
+        LOG.debug(String.format("Loading all %s-s", model.getName()));
+        int lastIndex = getConfig().getInt(modelIndexingPropName, 0);
+        for(int i=1; i<=lastIndex; i++) {
+            try {
+                T item = load(model, i);
+                if ((filter == null) || filter.is_conform(item)) {
+                    list.add(item);
+                }
+            } catch (ItemNotFound ignored) {
+            }
+        }
+        return list;
+    }
+
+    @Override
+    public synchronized <T extends Indexed> List<T> loadAll(Class<T> model) {
+        return loadAll(model, new OnlyOwnersFilteringStrategy(this.context.getUsername()));
+    }
+
+    @Override
+    public synchronized void delete(Class model, int id) {
+        LOG.debug(String.format("Deleting %s:%d", model.getName(), id));
+        String modelPropName = getItemPropertyName(model, id);
+        clear(modelPropName);
+    }
+
+    @Override
+    public boolean exists(Class model, int id) {
+        return getConfig().containsKey(getItemPropertyName(model, id));
+    }
+
+    private String getIndexPropertyName(Class model) {
+        return String.format("%s:index", model.getName());
+    }
+
+    private String getItemPropertyName(Class model, int id) {
+        return String.format("%s.%d", model.getName(), id);
+    }
+}

http://git-wip-us.apache.org/repos/asf/ambari/blob/5eb22214/contrib/views/pig/src/main/java/org/apache/ambari/view/pig/persistence/LocalKeyValueStorage.java
----------------------------------------------------------------------
diff --git a/contrib/views/pig/src/main/java/org/apache/ambari/view/pig/persistence/LocalKeyValueStorage.java b/contrib/views/pig/src/main/java/org/apache/ambari/view/pig/persistence/LocalKeyValueStorage.java
new file mode 100644
index 0000000..54dcb7f
--- /dev/null
+++ b/contrib/views/pig/src/main/java/org/apache/ambari/view/pig/persistence/LocalKeyValueStorage.java
@@ -0,0 +1,61 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.ambari.view.pig.persistence;
+
+import org.apache.ambari.view.ViewContext;
+import org.apache.commons.configuration.ConfigurationException;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import javax.xml.ws.WebServiceException;
+
+/**
+ * Persistent storage engine for storing java beans to
+ * properties file
+ * Path to file should be in 'dataworker.storagePath' parameter
+ */
+public class LocalKeyValueStorage extends KeyValueStorage {
+    private final static Logger LOG =
+            LoggerFactory.getLogger(LocalKeyValueStorage.class);
+
+    private PersistentConfiguration config = null;
+
+    public LocalKeyValueStorage(ViewContext context) {
+        super(context);
+    }
+
+    @Override
+    protected synchronized PersistentConfiguration getConfig() {
+        if (config == null) {
+            String fileName = context.getProperties().get("dataworker.storagePath");
+            if (fileName == null) {
+                String msg = "dataworker.storagePath is not configured!";
+                LOG.error(msg);
+                throw new WebServiceException(msg);
+            }
+            try {
+                config = new PersistentConfiguration(fileName);
+            } catch (ConfigurationException e) {
+                e.printStackTrace();
+            }
+        }
+        return config;
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/ambari/blob/5eb22214/contrib/views/pig/src/main/java/org/apache/ambari/view/pig/persistence/PersistentConfiguration.java
----------------------------------------------------------------------
diff --git a/contrib/views/pig/src/main/java/org/apache/ambari/view/pig/persistence/PersistentConfiguration.java b/contrib/views/pig/src/main/java/org/apache/ambari/view/pig/persistence/PersistentConfiguration.java
new file mode 100644
index 0000000..7e191f2
--- /dev/null
+++ b/contrib/views/pig/src/main/java/org/apache/ambari/view/pig/persistence/PersistentConfiguration.java
@@ -0,0 +1,42 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.ambari.view.pig.persistence;
+
+import org.apache.commons.configuration.ConfigurationException;
+import org.apache.commons.configuration.PropertiesConfiguration;
+import org.apache.commons.configuration.reloading.FileChangedReloadingStrategy;
+
+import java.io.File;
+
+public class PersistentConfiguration extends PropertiesConfiguration {
+    public PersistentConfiguration(String fileName) throws ConfigurationException {
+        super();
+
+        File config = new File(fileName);
+        setFile(config);
+        this.setAutoSave(true);
+        this.setReloadingStrategy(new FileChangedReloadingStrategy());
+        this.setDelimiterParsingDisabled(true);
+        this.setListDelimiter((char) 0);
+
+        if (config.exists()) {
+            this.load();
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/ambari/blob/5eb22214/contrib/views/pig/src/main/java/org/apache/ambari/view/pig/persistence/Storage.java
----------------------------------------------------------------------
diff --git a/contrib/views/pig/src/main/java/org/apache/ambari/view/pig/persistence/Storage.java b/contrib/views/pig/src/main/java/org/apache/ambari/view/pig/persistence/Storage.java
new file mode 100644
index 0000000..1507918
--- /dev/null
+++ b/contrib/views/pig/src/main/java/org/apache/ambari/view/pig/persistence/Storage.java
@@ -0,0 +1,39 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.ambari.view.pig.persistence;
+
+import org.apache.ambari.view.pig.persistence.utils.FilteringStrategy;
+import org.apache.ambari.view.pig.persistence.utils.Indexed;
+import org.apache.ambari.view.pig.persistence.utils.ItemNotFound;
+
+import java.util.List;
+
+public interface Storage {
+    void store(Indexed obj);
+
+    <T extends Indexed> T load(Class<T> model, int id) throws ItemNotFound;
+
+    <T extends Indexed> List<T> loadAll(Class<T> model, FilteringStrategy filter);
+
+    <T extends Indexed> List<T> loadAll(Class<T> model);
+
+    void delete(Class model, int id);
+
+    boolean exists(Class model, int id);
+}

http://git-wip-us.apache.org/repos/asf/ambari/blob/5eb22214/contrib/views/pig/src/main/java/org/apache/ambari/view/pig/persistence/utils/ContextConfigurationAdapter.java
----------------------------------------------------------------------
diff --git a/contrib/views/pig/src/main/java/org/apache/ambari/view/pig/persistence/utils/ContextConfigurationAdapter.java b/contrib/views/pig/src/main/java/org/apache/ambari/view/pig/persistence/utils/ContextConfigurationAdapter.java
new file mode 100644
index 0000000..829905d
--- /dev/null
+++ b/contrib/views/pig/src/main/java/org/apache/ambari/view/pig/persistence/utils/ContextConfigurationAdapter.java
@@ -0,0 +1,250 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.ambari.view.pig.persistence.utils;
+
+import org.apache.ambari.view.ViewContext;
+import org.apache.commons.configuration.Configuration;
+
+import java.math.BigDecimal;
+import java.math.BigInteger;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Properties;
+
+public class ContextConfigurationAdapter implements Configuration {
+    private ViewContext context;
+
+    public ContextConfigurationAdapter(ViewContext context) {
+        this.context = context;
+    }
+
+    @Override
+    public Configuration subset(String prefix) {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public boolean isEmpty() {
+        return context.getInstanceData().isEmpty();
+    }
+
+    @Override
+    public boolean containsKey(String s) {
+        return context.getInstanceData().containsKey(s);
+    }
+
+    @Override
+    public void addProperty(String s, Object o) {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public void setProperty(String s, Object o) {
+        context.putInstanceData(s, o.toString());
+    }
+
+    @Override
+    public void clearProperty(String key) {
+        context.removeInstanceData(key);
+    }
+
+    @Override
+    public void clear() {
+        for (String key : context.getInstanceData().keySet())
+            context.removeInstanceData(key);
+    }
+
+    @Override
+    public Object getProperty(String key) {
+        return context.getInstanceData(key);
+    }
+
+    @Override
+    public Iterator getKeys(String s) {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public Iterator getKeys() {
+        return context.getInstanceData().keySet().iterator();
+    }
+
+    @Override
+    public Properties getProperties(String s) {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public boolean getBoolean(String s) {
+        return getBoolean(s, null);
+    }
+
+    @Override
+    public boolean getBoolean(String s, boolean b) {
+        return getBoolean(s, (Boolean)b);
+    }
+
+    @Override
+    public Boolean getBoolean(String s, Boolean aBoolean) {
+        String data = context.getInstanceData(s);
+        return (data != null)?Boolean.parseBoolean(data):aBoolean;
+    }
+
+    @Override
+    public byte getByte(String s) {
+        return getByte(s, null);
+    }
+
+    @Override
+    public byte getByte(String s, byte b) {
+        return getByte(s, (Byte)b);
+    }
+
+    @Override
+    public Byte getByte(String s, Byte aByte) {
+        String data = context.getInstanceData(s);
+        return (data != null)?Byte.parseByte(data):aByte;
+    }
+
+    @Override
+    public double getDouble(String s) {
+        return getDouble(s, null);
+    }
+
+    @Override
+    public double getDouble(String s, double v) {
+        return getDouble(s, (Double)v);
+    }
+
+    @Override
+    public Double getDouble(String s, Double aDouble) {
+        String data = context.getInstanceData(s);
+        return (data != null)?Double.parseDouble(data):aDouble;
+    }
+
+    @Override
+    public float getFloat(String s) {
+        return getFloat(s, null);
+    }
+
+    @Override
+    public float getFloat(String s, float v) {
+        return getFloat(s, (Float)v);
+    }
+
+    @Override
+    public Float getFloat(String s, Float aFloat) {
+        String data = context.getInstanceData(s);
+        return (data != null)?Float.parseFloat(data):aFloat;
+    }
+
+    @Override
+    public int getInt(String s) {
+        return getInteger(s, null);
+    }
+
+    @Override
+    public int getInt(String s, int i) {
+        return getInteger(s, i);
+    }
+
+    @Override
+    public Integer getInteger(String s, Integer integer) {
+        String data = context.getInstanceData(s);
+        return (data != null)?Integer.parseInt(data):integer;
+    }
+
+    @Override
+    public long getLong(String s) {
+        return getLong(s, null);
+    }
+
+    @Override
+    public long getLong(String s, long l) {
+        return getLong(s, (Long)l);
+    }
+
+    @Override
+    public Long getLong(String s, Long aLong) {
+        String data = context.getInstanceData(s);
+        return (data != null)?Long.parseLong(data):aLong;
+    }
+
+    @Override
+    public short getShort(String s) {
+        return getShort(s, null);
+    }
+
+    @Override
+    public short getShort(String s, short i) {
+        return getShort(s, (Short)i);
+    }
+
+    @Override
+    public Short getShort(String s, Short aShort) {
+        String data = context.getInstanceData(s);
+        return (data != null)?Short.parseShort(data):aShort;
+    }
+
+    @Override
+    public BigDecimal getBigDecimal(String s) {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public BigDecimal getBigDecimal(String s, BigDecimal bigDecimal) {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public BigInteger getBigInteger(String s) {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public BigInteger getBigInteger(String s, BigInteger bigInteger) {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public String getString(String s) {
+        return context.getInstanceData(s);
+    }
+
+    @Override
+    public String getString(String s, String s2) {
+        String data = getString(s);
+        return (data != null)?data:s2;
+    }
+
+    @Override
+    public String[] getStringArray(String s) {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public List getList(String s) {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public List getList(String s, List list) {
+        throw new UnsupportedOperationException();
+    }
+}

http://git-wip-us.apache.org/repos/asf/ambari/blob/5eb22214/contrib/views/pig/src/main/java/org/apache/ambari/view/pig/persistence/utils/FilteringStrategy.java
----------------------------------------------------------------------
diff --git a/contrib/views/pig/src/main/java/org/apache/ambari/view/pig/persistence/utils/FilteringStrategy.java b/contrib/views/pig/src/main/java/org/apache/ambari/view/pig/persistence/utils/FilteringStrategy.java
new file mode 100644
index 0000000..75a0953
--- /dev/null
+++ b/contrib/views/pig/src/main/java/org/apache/ambari/view/pig/persistence/utils/FilteringStrategy.java
@@ -0,0 +1,23 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.ambari.view.pig.persistence.utils;
+
+public interface FilteringStrategy {
+    boolean is_conform(Indexed item);
+}

http://git-wip-us.apache.org/repos/asf/ambari/blob/5eb22214/contrib/views/pig/src/main/java/org/apache/ambari/view/pig/persistence/utils/Indexed.java
----------------------------------------------------------------------
diff --git a/contrib/views/pig/src/main/java/org/apache/ambari/view/pig/persistence/utils/Indexed.java b/contrib/views/pig/src/main/java/org/apache/ambari/view/pig/persistence/utils/Indexed.java
new file mode 100644
index 0000000..cbe2016
--- /dev/null
+++ b/contrib/views/pig/src/main/java/org/apache/ambari/view/pig/persistence/utils/Indexed.java
@@ -0,0 +1,24 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.ambari.view.pig.persistence.utils;
+
+public interface Indexed {
+    String getId();
+    void setId(String id);
+}

http://git-wip-us.apache.org/repos/asf/ambari/blob/5eb22214/contrib/views/pig/src/main/java/org/apache/ambari/view/pig/persistence/utils/ItemNotFound.java
----------------------------------------------------------------------
diff --git a/contrib/views/pig/src/main/java/org/apache/ambari/view/pig/persistence/utils/ItemNotFound.java b/contrib/views/pig/src/main/java/org/apache/ambari/view/pig/persistence/utils/ItemNotFound.java
new file mode 100644
index 0000000..df56036
--- /dev/null
+++ b/contrib/views/pig/src/main/java/org/apache/ambari/view/pig/persistence/utils/ItemNotFound.java
@@ -0,0 +1,22 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.ambari.view.pig.persistence.utils;
+
+public class ItemNotFound extends Exception {
+}

http://git-wip-us.apache.org/repos/asf/ambari/blob/5eb22214/contrib/views/pig/src/main/java/org/apache/ambari/view/pig/persistence/utils/OnlyOwnersFilteringStrategy.java
----------------------------------------------------------------------
diff --git a/contrib/views/pig/src/main/java/org/apache/ambari/view/pig/persistence/utils/OnlyOwnersFilteringStrategy.java b/contrib/views/pig/src/main/java/org/apache/ambari/view/pig/persistence/utils/OnlyOwnersFilteringStrategy.java
new file mode 100644
index 0000000..7964cf7
--- /dev/null
+++ b/contrib/views/pig/src/main/java/org/apache/ambari/view/pig/persistence/utils/OnlyOwnersFilteringStrategy.java
@@ -0,0 +1,33 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.ambari.view.pig.persistence.utils;
+
+public class OnlyOwnersFilteringStrategy implements FilteringStrategy {
+    private final String username;
+
+    public OnlyOwnersFilteringStrategy(String username) {
+        this.username = username;
+    }
+
+    @Override
+    public boolean is_conform(Indexed item) {
+        Owned object = (Owned) item;
+        return object.getOwner().compareTo(username) == 0;
+    }
+}

http://git-wip-us.apache.org/repos/asf/ambari/blob/5eb22214/contrib/views/pig/src/main/java/org/apache/ambari/view/pig/persistence/utils/Owned.java
----------------------------------------------------------------------
diff --git a/contrib/views/pig/src/main/java/org/apache/ambari/view/pig/persistence/utils/Owned.java b/contrib/views/pig/src/main/java/org/apache/ambari/view/pig/persistence/utils/Owned.java
new file mode 100644
index 0000000..30918a2
--- /dev/null
+++ b/contrib/views/pig/src/main/java/org/apache/ambari/view/pig/persistence/utils/Owned.java
@@ -0,0 +1,24 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.ambari.view.pig.persistence.utils;
+
+public interface Owned {
+    String getOwner();
+    void setOwner(String owner);
+}

http://git-wip-us.apache.org/repos/asf/ambari/blob/5eb22214/contrib/views/pig/src/main/java/org/apache/ambari/view/pig/persistence/utils/PersonalResource.java
----------------------------------------------------------------------
diff --git a/contrib/views/pig/src/main/java/org/apache/ambari/view/pig/persistence/utils/PersonalResource.java b/contrib/views/pig/src/main/java/org/apache/ambari/view/pig/persistence/utils/PersonalResource.java
new file mode 100644
index 0000000..3096071
--- /dev/null
+++ b/contrib/views/pig/src/main/java/org/apache/ambari/view/pig/persistence/utils/PersonalResource.java
@@ -0,0 +1,22 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.ambari.view.pig.persistence.utils;
+
+public interface PersonalResource extends Indexed, Owned {
+}

http://git-wip-us.apache.org/repos/asf/ambari/blob/5eb22214/contrib/views/pig/src/main/java/org/apache/ambari/view/pig/persistence/utils/StorageUtil.java
----------------------------------------------------------------------
diff --git a/contrib/views/pig/src/main/java/org/apache/ambari/view/pig/persistence/utils/StorageUtil.java b/contrib/views/pig/src/main/java/org/apache/ambari/view/pig/persistence/utils/StorageUtil.java
new file mode 100644
index 0000000..0c7b25b
--- /dev/null
+++ b/contrib/views/pig/src/main/java/org/apache/ambari/view/pig/persistence/utils/StorageUtil.java
@@ -0,0 +1,53 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.ambari.view.pig.persistence.utils;
+
+import org.apache.ambari.view.ViewContext;
+import org.apache.ambari.view.pig.persistence.InstanceKeyValueStorage;
+import org.apache.ambari.view.pig.persistence.LocalKeyValueStorage;
+import org.apache.ambari.view.pig.persistence.Storage;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class StorageUtil {
+    private static Storage storageInstance = null;
+
+    protected final static Logger LOG =
+            LoggerFactory.getLogger(StorageUtil.class);
+
+    public synchronized static Storage getStorage(ViewContext context) {
+        if (storageInstance == null) {
+            String fileName = context.getProperties().get("dataworker.storagePath");
+            if (fileName != null) {
+                LOG.debug("Using local storage in " + fileName + " to store data");
+                // If specifed, use LocalKeyValueStorage - key-value file based storage
+                storageInstance = new LocalKeyValueStorage(context);
+            } else {
+                LOG.debug("Using Persistence API to store data");
+                // If not specifed, use ambari-views Persistence API
+                storageInstance = new InstanceKeyValueStorage(context);
+            }
+        }
+        return storageInstance;
+    }
+
+    public static void setStorage(Storage storage) {
+        storageInstance = storage;
+    }
+}

http://git-wip-us.apache.org/repos/asf/ambari/blob/5eb22214/contrib/views/pig/src/main/java/org/apache/ambari/view/pig/resources/CRUDResourceManager.java
----------------------------------------------------------------------
diff --git a/contrib/views/pig/src/main/java/org/apache/ambari/view/pig/resources/CRUDResourceManager.java b/contrib/views/pig/src/main/java/org/apache/ambari/view/pig/resources/CRUDResourceManager.java
new file mode 100644
index 0000000..9319d3b
--- /dev/null
+++ b/contrib/views/pig/src/main/java/org/apache/ambari/view/pig/resources/CRUDResourceManager.java
@@ -0,0 +1,91 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.ambari.view.pig.resources;
+
+import org.apache.ambari.view.ViewContext;
+import org.apache.ambari.view.pig.persistence.Storage;
+import org.apache.ambari.view.pig.persistence.utils.FilteringStrategy;
+import org.apache.ambari.view.pig.persistence.utils.Indexed;
+import org.apache.ambari.view.pig.persistence.utils.ItemNotFound;
+import org.apache.ambari.view.pig.persistence.utils.StorageUtil;
+
+import java.util.List;
+
+/**
+ * CRUD resource manager
+ * @param <T> Data type with ID
+ */
+abstract public class CRUDResourceManager<T extends Indexed> {
+    private Storage storage = null;
+
+    protected final Class<T> resourceClass;
+
+    public CRUDResourceManager(Class<T> responseClass) {
+        this.resourceClass = responseClass;
+    }
+    // CRUD operations
+
+    public T create(T object) {
+        object.setId(null);
+        return this.save(object);
+    }
+
+    public T read(String id) throws ItemNotFound {
+        T object = null;
+        object = getPigStorage().load(this.resourceClass, Integer.parseInt(id));
+        if (!checkPermissions(object))
+            throw new ItemNotFound();
+        return object;
+    }
+
+    public List<T> readAll(FilteringStrategy filteringStrategy) {
+        return getPigStorage().loadAll(this.resourceClass, filteringStrategy);
+    }
+
+    public T update(T newObject, String id) throws ItemNotFound {
+        newObject.setId(id);
+        this.save(newObject);
+        return newObject;
+    }
+
+    public void delete(String resourceId) throws ItemNotFound {
+        int id = Integer.parseInt(resourceId);
+        if (!getPigStorage().exists(this.resourceClass, id)) {
+            throw new ItemNotFound();
+        }
+        getPigStorage().delete(this.resourceClass, id);
+    }
+
+    // UTILS
+
+    protected T save(T object) {
+        getPigStorage().store(object);
+        return object;
+    }
+
+    protected Storage getPigStorage() {
+        if (storage == null) {
+            storage = StorageUtil.getStorage(getContext());
+        }
+        return storage;
+    }
+
+    protected abstract boolean checkPermissions(T object);
+    protected abstract ViewContext getContext();
+}

http://git-wip-us.apache.org/repos/asf/ambari/blob/5eb22214/contrib/views/pig/src/main/java/org/apache/ambari/view/pig/resources/PersonalCRUDResourceManager.java
----------------------------------------------------------------------
diff --git a/contrib/views/pig/src/main/java/org/apache/ambari/view/pig/resources/PersonalCRUDResourceManager.java b/contrib/views/pig/src/main/java/org/apache/ambari/view/pig/resources/PersonalCRUDResourceManager.java
new file mode 100644
index 0000000..ffccfd9
--- /dev/null
+++ b/contrib/views/pig/src/main/java/org/apache/ambari/view/pig/resources/PersonalCRUDResourceManager.java
@@ -0,0 +1,81 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.ambari.view.pig.resources;
+
+import org.apache.ambari.view.ViewContext;
+import org.apache.ambari.view.pig.persistence.utils.ItemNotFound;
+import org.apache.ambari.view.pig.persistence.utils.PersonalResource;
+
+import java.util.concurrent.Callable;
+
+/**
+ * Resource manager that returns only user owned elements from DB
+ * @param <T> Data type with ID and Owner
+ */
+public class PersonalCRUDResourceManager<T extends PersonalResource> extends CRUDResourceManager<T> {
+    protected ViewContext context;
+    protected boolean ignorePermissions = false;
+
+    public PersonalCRUDResourceManager(Class<T> responseClass, ViewContext context) {
+        super(responseClass);
+        this.context = context;
+    }
+
+    public T update(T newObject, String id) throws ItemNotFound {
+        T object = getPigStorage().load(this.resourceClass, Integer.parseInt(id));
+        if (object.getOwner().compareTo(this.context.getUsername()) != 0) {
+            throw new ItemNotFound();
+        }
+
+        newObject.setOwner(this.context.getUsername());
+        return super.update(newObject, id);
+    }
+
+    public T save(T object) {
+        object.setOwner(this.context.getUsername());
+        return super.save(object);
+    }
+
+    @Override
+    protected boolean checkPermissions(T object) {
+        if (ignorePermissions)
+            return true;
+        return object.getOwner().compareTo(this.context.getUsername()) == 0;
+    }
+
+    @Override
+    protected ViewContext getContext() {
+        return context;
+    }
+
+    public <T> T ignorePermissions(String fakeUser, Callable<T> actions) throws Exception {
+        ignorePermissions = true;
+        T result;
+        try {
+            result = actions.call();
+        } finally {
+            ignorePermissions = false;
+        }
+        return result;
+    }
+
+    public <T> T ignorePermissions(Callable<T> actions) throws Exception {
+        return ignorePermissions("", actions);
+    }
+}

http://git-wip-us.apache.org/repos/asf/ambari/blob/5eb22214/contrib/views/pig/src/main/java/org/apache/ambari/view/pig/resources/SharedCRUDResourceManager.java
----------------------------------------------------------------------
diff --git a/contrib/views/pig/src/main/java/org/apache/ambari/view/pig/resources/SharedCRUDResourceManager.java b/contrib/views/pig/src/main/java/org/apache/ambari/view/pig/resources/SharedCRUDResourceManager.java
new file mode 100644
index 0000000..be89d36
--- /dev/null
+++ b/contrib/views/pig/src/main/java/org/apache/ambari/view/pig/resources/SharedCRUDResourceManager.java
@@ -0,0 +1,45 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.ambari.view.pig.resources;
+
+import org.apache.ambari.view.ViewContext;
+import org.apache.ambari.view.pig.persistence.utils.Indexed;
+
+/**
+ * Resource manager that doesn't restrict access (Allow all)
+ * @param <T> Data type with ID
+ */
+public class SharedCRUDResourceManager<T extends Indexed> extends CRUDResourceManager<T> {
+    protected ViewContext context;
+
+    public SharedCRUDResourceManager(Class<T> responseClass, ViewContext context) {
+        super(responseClass);
+        this.context = context;
+    }
+
+    @Override
+    protected boolean checkPermissions(T object) {
+        return true; //everyone has permission
+    }
+
+    @Override
+    protected ViewContext getContext() {
+        return context;
+    }
+}

http://git-wip-us.apache.org/repos/asf/ambari/blob/5eb22214/contrib/views/pig/src/main/java/org/apache/ambari/view/pig/resources/files/FileResource.java
----------------------------------------------------------------------
diff --git a/contrib/views/pig/src/main/java/org/apache/ambari/view/pig/resources/files/FileResource.java b/contrib/views/pig/src/main/java/org/apache/ambari/view/pig/resources/files/FileResource.java
new file mode 100644
index 0000000..9ae45c7
--- /dev/null
+++ b/contrib/views/pig/src/main/java/org/apache/ambari/view/pig/resources/files/FileResource.java
@@ -0,0 +1,27 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.ambari.view.pig.resources.files;
+
+public class FileResource {
+    public String filePath;
+    public String fileContent;
+    public boolean hasNext;
+    public long page;
+    public long pageCount;
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/ambari/blob/5eb22214/contrib/views/pig/src/main/java/org/apache/ambari/view/pig/resources/files/FileService.java
----------------------------------------------------------------------
diff --git a/contrib/views/pig/src/main/java/org/apache/ambari/view/pig/resources/files/FileService.java b/contrib/views/pig/src/main/java/org/apache/ambari/view/pig/resources/files/FileService.java
new file mode 100644
index 0000000..c36c582
--- /dev/null
+++ b/contrib/views/pig/src/main/java/org/apache/ambari/view/pig/resources/files/FileService.java
@@ -0,0 +1,141 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.ambari.view.pig.resources.files;
+
+import com.google.inject.Inject;
+import org.apache.ambari.view.ViewResourceHandler;
+import org.apache.ambari.view.pig.services.BaseService;
+import org.apache.ambari.view.pig.utils.FilePaginator;
+import org.apache.hadoop.fs.FSDataOutputStream;
+import org.apache.hadoop.fs.FileAlreadyExistsException;
+import org.json.simple.JSONObject;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import javax.servlet.http.HttpServletResponse;
+import javax.ws.rs.*;
+import javax.ws.rs.core.*;
+import java.io.FileNotFoundException;
+import java.io.IOException;
+
+/**
+ * File access resource
+ * API:
+ * GET /:path
+ *      read entire file
+ * POST /
+ *      create new file
+ *      Required: filePath
+ *      file should not already exists
+ * PUT /:path
+ *      update file content
+ */
+public class FileService extends BaseService {
+    @Inject
+    ViewResourceHandler handler;
+
+    protected final static Logger LOG =
+            LoggerFactory.getLogger(FileService.class);
+
+    /**
+     * Get single item
+     */
+    @GET
+    @Path("{filePath:.*}")
+    @Produces(MediaType.APPLICATION_JSON)
+    public Response getFile(@PathParam("filePath") String filePath, @QueryParam("page") Long page) throws IOException, InterruptedException {
+        LOG.debug("Reading file " + filePath);
+        try {
+            FilePaginator paginator = new FilePaginator(filePath, context);
+
+            if (page == null)
+                page = 0L;
+
+            FileResource file = new FileResource();
+            file.filePath = filePath;
+            file.fileContent = paginator.readPage(page);
+            file.hasNext = paginator.pageCount() > page + 1;
+            file.page = page;
+            file.pageCount = paginator.pageCount();
+
+            JSONObject object = new JSONObject();
+            object.put("file", file);
+            return Response.ok(object).status(200).build();
+        } catch (FileNotFoundException e) {
+            return notFoundResponse(e.toString());
+        } catch (IllegalArgumentException e) {
+            return badRequestResponse(e.toString());
+        }
+    }
+
+    /**
+     * Delete single item
+     */
+    @DELETE
+    @Path("{filePath:.*}")
+    public Response deleteFile(@PathParam("filePath") String filePath) throws IOException, InterruptedException {
+        LOG.debug("Deleting file " + filePath);
+        if (getHdfsApi().delete(filePath, false)) {
+            return Response.status(204).build();
+        }
+        return notFoundResponse("FileSystem.delete returned false");
+    }
+
+    /**
+     * Update item
+     */
+    @PUT
+    @Path("{filePath:.*}")
+    @Consumes(MediaType.APPLICATION_JSON)
+    public Response updateFile(FileResourceRequest request,
+                               @PathParam("filePath") String filePath) throws IOException, InterruptedException {
+        LOG.debug("Rewriting file " + filePath);
+        FSDataOutputStream output = getHdfsApi().create(filePath, true);
+        output.writeBytes(request.file.fileContent);
+        output.close();
+        return Response.status(204).build();
+    }
+
+    /**
+     * Create script
+     */
+    @POST
+    @Consumes(MediaType.APPLICATION_JSON)
+    public Response createFile(FileResourceRequest request,
+                               @Context HttpServletResponse response, @Context UriInfo ui)
+            throws IOException, InterruptedException {
+        LOG.debug("Creating file " + request.file.filePath);
+        try {
+            FSDataOutputStream output = getHdfsApi().create(request.file.filePath, false);
+            if (request.file.fileContent != null) {
+                output.writeBytes(request.file.fileContent);
+            }
+            output.close();
+        } catch (FileAlreadyExistsException e) {
+            return badRequestResponse(e.toString());
+        }
+        response.setHeader("Location",
+                String.format("%s/%s", ui.getAbsolutePath().toString(), request.file.filePath));
+        return Response.status(204).build();
+    }
+
+    public static class FileResourceRequest {
+        public FileResource file;
+    }
+}

http://git-wip-us.apache.org/repos/asf/ambari/blob/5eb22214/contrib/views/pig/src/main/java/org/apache/ambari/view/pig/resources/jobs/JobResourceManager.java
----------------------------------------------------------------------
diff --git a/contrib/views/pig/src/main/java/org/apache/ambari/view/pig/resources/jobs/JobResourceManager.java b/contrib/views/pig/src/main/java/org/apache/ambari/view/pig/resources/jobs/JobResourceManager.java
new file mode 100644
index 0000000..67a038b
--- /dev/null
+++ b/contrib/views/pig/src/main/java/org/apache/ambari/view/pig/resources/jobs/JobResourceManager.java
@@ -0,0 +1,280 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.ambari.view.pig.resources.jobs;
+
+import org.apache.ambari.view.ViewContext;
+import org.apache.ambari.view.pig.persistence.utils.FilteringStrategy;
+import org.apache.ambari.view.pig.persistence.utils.Indexed;
+import org.apache.ambari.view.pig.resources.PersonalCRUDResourceManager;
+import org.apache.ambari.view.pig.resources.jobs.models.PigJob;
+import org.apache.ambari.view.pig.resources.jobs.utils.JobPolling;
+import org.apache.ambari.view.pig.services.BaseService;
+import org.apache.ambari.view.pig.templeton.client.TempletonApi;
+import org.apache.hadoop.fs.FSDataOutputStream;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import javax.xml.ws.WebServiceException;
+import java.io.File;
+import java.io.IOException;
+import java.text.SimpleDateFormat;
+import java.util.Date;
+import java.util.List;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+/**
+ * Object that provides operations for templeton jobs
+ * CRUD overridden to support
+ */
+public class JobResourceManager extends PersonalCRUDResourceManager<PigJob> {
+    protected TempletonApi api;
+
+    private final static Logger LOG =
+            LoggerFactory.getLogger(JobResourceManager.class);
+
+    public JobResourceManager(ViewContext context) {
+        super(PigJob.class, context);
+        setupPolling();
+    }
+
+    public TempletonApi getTempletonApi() {
+        if (api == null) {
+            api = new TempletonApi(context.getProperties().get("dataworker.templeton_url"),
+                    getTempletonUser(), getTempletonUser(), context);
+        }
+        return api;
+    }
+
+    public void setTempletonApi(TempletonApi api) {
+        this.api = api;
+    }
+
+    private void setupPolling() {
+        List<PigJob> notCompleted = this.readAll(new FilteringStrategy() {
+            @Override
+            public boolean is_conform(Indexed item) {
+                PigJob job = (PigJob) item;
+                return job.isInProgress();
+            }
+        });
+
+        for(PigJob job : notCompleted) {
+            JobPolling.pollJob(context, job);
+        }
+    }
+
+    @Override
+    public PigJob create(PigJob object) {
+        object.setStatus(PigJob.Status.SUBMITTING);
+        PigJob job = super.create(object);
+        LOG.debug("Submitting job...");
+
+        try {
+            submitJob(object);
+        } catch (RuntimeException e) {
+            object.setStatus(PigJob.Status.SUBMIT_FAILED);
+            save(object);
+            LOG.debug("Job submit FAILED");
+            throw e;
+        }
+        LOG.debug("Job submit OK");
+        object.setStatus(PigJob.Status.SUBMITTED);
+        save(object);
+        return job;
+    }
+
+    public void killJob(PigJob object) throws IOException {
+        LOG.debug("Killing job...");
+
+        try {
+            getTempletonApi().killJob(object.getJobId());
+        } catch (IOException e) {
+            LOG.debug("Job kill FAILED");
+            throw e;
+        }
+        LOG.debug("Job kill OK");
+    }
+
+    /**
+     * Running job
+     * @param job job bean
+     */
+    private void submitJob(PigJob job) {
+        String date = new SimpleDateFormat("dd-MM-yyyy-HH-mm-ss").format(new Date());
+        String statusdir = String.format(context.getProperties().get("dataworker.pigJobsPath") +
+                "/%s/%s_%s", getTempletonUser(),
+                job.getTitle().toLowerCase().replaceAll("[^a-zA-Z0-9 ]+", "").replace(" ", "_"),
+                date);
+
+        String newPigScriptPath = statusdir + "/script.pig";
+        String newSourceFilePath = statusdir + "/source.pig";
+        String newPythonScriptPath = statusdir + "/udf.py";
+        String templetonParamsFilePath = statusdir + "/params";
+        try {
+            // additional file can be passed to copy into work directory
+            if (job.getSourceFileContent() != null && !job.getSourceFileContent().isEmpty()) {
+                String sourceFileContent = job.getSourceFileContent();
+                job.setSourceFileContent(null); // we should not store content in DB
+                save(job);
+
+                FSDataOutputStream stream = BaseService.getHdfsApi(context).create(newSourceFilePath, true);
+                stream.writeBytes(sourceFileContent);
+                stream.close();
+            } else {
+                if (job.getSourceFile() != null && !job.getSourceFile().isEmpty()) {
+                    // otherwise, just copy original file
+                    if (!BaseService.getHdfsApi(context).copy(job.getSourceFile(), newSourceFilePath)) {
+                        throw new WebServiceException("Can't copy source file from " + job.getSourceFile() +
+                                " to " + newPigScriptPath);
+                    }
+                }
+            }
+        } catch (IOException e) {
+            throw new WebServiceException("Can't create/copy source file: " + e.toString(), e);
+        } catch (InterruptedException e) {
+            throw new WebServiceException("Can't create/copy source file: " + e.toString(), e);
+        }
+
+        try {
+            // content can be passed from front-end with substituted arguments
+            if (job.getForcedContent() != null && !job.getForcedContent().isEmpty()) {
+                String forcedContent = job.getForcedContent();
+                // variable for sourceFile can be passed from front-ent
+                forcedContent = forcedContent.replace("${sourceFile}",
+                        context.getProperties().get("dataworker.defaultFs") + newSourceFilePath);
+                job.setForcedContent(null); // we should not store content in DB
+                save(job);
+
+                FSDataOutputStream stream = BaseService.getHdfsApi(context).create(newPigScriptPath, true);
+                stream.writeBytes(forcedContent);
+                stream.close();
+            } else {
+                // otherwise, just copy original file
+                if (!BaseService.getHdfsApi(context).copy(job.getPigScript(), newPigScriptPath)) {
+                    throw new WebServiceException("Can't copy pig script file from " + job.getPigScript() +
+                                                    " to " + newPigScriptPath);
+                }
+            }
+        } catch (IOException e) {
+            throw new WebServiceException("Can't create/copy pig script file: " + e.toString(), e);
+        } catch (InterruptedException e) {
+            throw new WebServiceException("Can't create/copy pig script file: " + e.toString(), e);
+        }
+
+        if (job.getPythonScript() != null && !job.getPythonScript().isEmpty()) {
+            try {
+                if (!BaseService.getHdfsApi(context).copy(job.getPythonScript(), newPythonScriptPath)) {
+                    throw new WebServiceException("Can't copy python udf script file from " + job.getPythonScript() +
+                            " to " + newPythonScriptPath);
+                }
+            } catch (IOException e) {
+                throw new WebServiceException("Can't create/copy python udf file: " + e.toString(), e);
+            } catch (InterruptedException e) {
+                throw new WebServiceException("Can't create/copy python udf file: " + e.toString(), e);
+            }
+        }
+
+        try {
+            FSDataOutputStream stream = BaseService.getHdfsApi(context).create(templetonParamsFilePath, true);
+            if (job.getTempletonArguments() != null) {
+                stream.writeBytes(job.getTempletonArguments());
+            }
+            stream.close();
+        } catch (IOException e) {
+            throw new WebServiceException("Can't create params file: " + e.toString(), e);
+        } catch (InterruptedException e) {
+            throw new WebServiceException("Can't create params file: " + e.toString(), e);
+        }
+        job.setPigScript(newPigScriptPath);
+
+        job.setStatusDir(statusdir);
+        job.setDateStarted(System.currentTimeMillis() / 1000L);
+
+        TempletonApi.JobData data = null;
+        try {
+            data = getTempletonApi().runPigQuery(new File(job.getPigScript()), statusdir, job.getTempletonArguments());
+        } catch (IOException templetonBadResponse) {
+            String msg = String.format("Templeton bad response: %s", templetonBadResponse.toString());
+            LOG.debug(msg);
+            throw new WebServiceException(msg, templetonBadResponse);
+        }
+        job.setJobId(data.id);
+
+        JobPolling.pollJob(context, job);
+    }
+
+    public void retrieveJobStatus(PigJob job) {
+        TempletonApi.JobInfo info = null;
+        try {
+            info = getTempletonApi().checkJob(job.getJobId());
+        } catch (IOException e) {
+            LOG.warn(String.format("IO Exception: %s", e));
+            return;
+        }
+
+        if (info.status != null && (info.status.containsKey("runState"))) {
+            //TODO: retrieve from RM
+            int runState = ((Double) info.status.get("runState")).intValue();
+            switch (runState) {
+                case PigJob.RUN_STATE_KILLED:
+                    LOG.debug(String.format("Job KILLED: %s", job.getJobId()));
+                    job.setStatus(PigJob.Status.KILLED);
+                    break;
+                case PigJob.RUN_STATE_FAILED:
+                    LOG.debug(String.format("Job FAILED: %s", job.getJobId()));
+                    job.setStatus(PigJob.Status.FAILED);
+                    break;
+                case PigJob.RUN_STATE_PREP:
+                case PigJob.RUN_STATE_RUNNING:
+                    job.setStatus(PigJob.Status.RUNNING);
+                    break;
+                case PigJob.RUN_STATE_SUCCEEDED:
+                    LOG.debug(String.format("Job COMPLETED: %s", job.getJobId()));
+                    job.setStatus(PigJob.Status.COMPLETED);
+                    break;
+                default:
+                    LOG.debug(String.format("Job in unknown state: %s", job.getJobId()));
+                    job.setStatus(PigJob.Status.UNKNOWN);
+                    break;
+            }
+        }
+        Pattern pattern = Pattern.compile("\\d+");
+        Matcher matcher = null;
+        if (info.percentComplete != null) {
+            matcher = pattern.matcher(info.percentComplete);
+        }
+        if (matcher != null && matcher.find()) {
+            job.setPercentComplete(Integer.valueOf(matcher.group()));
+        } else {
+            job.setPercentComplete(null);
+        }
+        save(job);
+    }
+
+    /**
+     * Extension point to use different usernames in templeton
+     * requests instead of logged in user
+     * @return username in templeton
+     */
+    private String getTempletonUser() {
+        return context.getProperties().get("dataworker.templeton_user");
+//        return context.getTempletonUser();
+    }
+}

http://git-wip-us.apache.org/repos/asf/ambari/blob/5eb22214/contrib/views/pig/src/main/java/org/apache/ambari/view/pig/resources/jobs/JobResourceProvider.java
----------------------------------------------------------------------
diff --git a/contrib/views/pig/src/main/java/org/apache/ambari/view/pig/resources/jobs/JobResourceProvider.java b/contrib/views/pig/src/main/java/org/apache/ambari/view/pig/resources/jobs/JobResourceProvider.java
new file mode 100644
index 0000000..9981952
--- /dev/null
+++ b/contrib/views/pig/src/main/java/org/apache/ambari/view/pig/resources/jobs/JobResourceProvider.java
@@ -0,0 +1,100 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.ambari.view.pig.resources.jobs;
+
+import com.google.inject.Inject;
+import org.apache.ambari.view.*;
+import org.apache.ambari.view.pig.persistence.utils.ItemNotFound;
+import org.apache.ambari.view.pig.persistence.utils.OnlyOwnersFilteringStrategy;
+import org.apache.ambari.view.pig.resources.jobs.models.PigJob;
+
+import java.lang.reflect.InvocationTargetException;
+import java.util.HashSet;
+import java.util.Map;
+import java.util.Set;
+
+public class JobResourceProvider implements ResourceProvider<PigJob> {
+    @Inject
+    ViewContext context;
+
+    protected JobResourceManager resourceManager = null;
+
+    protected synchronized JobResourceManager getResourceManager() {
+        if (resourceManager == null) {
+            resourceManager = new JobResourceManager(context);
+        }
+        return resourceManager;
+    }
+
+    @Override
+    public PigJob getResource(String resourceId, Set<String> strings) throws SystemException, NoSuchResourceException, UnsupportedPropertyException {
+        try {
+            return getResourceManager().read(resourceId);
+        } catch (ItemNotFound itemNotFound) {
+            throw new NoSuchResourceException(resourceId);
+        }
+    }
+
+    @Override
+    public Set<PigJob> getResources(ReadRequest readRequest) throws SystemException, NoSuchResourceException, UnsupportedPropertyException {
+        return new HashSet<PigJob>(getResourceManager().readAll(
+                new OnlyOwnersFilteringStrategy(this.context.getUsername())));
+    }
+
+    @Override
+    public void createResource(String s, Map<String, Object> stringObjectMap) throws SystemException, ResourceAlreadyExistsException, NoSuchResourceException, UnsupportedPropertyException {
+        PigJob job = null;
+        try {
+            job = new PigJob(stringObjectMap);
+        } catch (InvocationTargetException e) {
+            throw new SystemException("error on creating resource", e);
+        } catch (IllegalAccessException e) {
+            throw new SystemException("error on creating resource", e);
+        }
+        getResourceManager().create(job);
+    }
+
+    @Override
+    public boolean updateResource(String resourceId, Map<String, Object> stringObjectMap) throws SystemException, NoSuchResourceException, UnsupportedPropertyException {
+        PigJob job = null;
+        try {
+            job = new PigJob(stringObjectMap);
+        } catch (InvocationTargetException e) {
+            throw new SystemException("error on updating resource", e);
+        } catch (IllegalAccessException e) {
+            throw new SystemException("error on updating resource", e);
+        }
+        try {
+            getResourceManager().update(job, resourceId);
+        } catch (ItemNotFound itemNotFound) {
+            throw new NoSuchResourceException(resourceId);
+        }
+        return true;
+    }
+
+    @Override
+    public boolean deleteResource(String resourceId) throws SystemException, NoSuchResourceException, UnsupportedPropertyException {
+        try {
+            getResourceManager().delete(resourceId);
+        } catch (ItemNotFound itemNotFound) {
+            throw new NoSuchResourceException(resourceId);
+        }
+        return true;
+    }
+}


[3/7] AMBARI-5616 - Ambari Views: Pig view (Roman Rader via tbeerbower)

Posted by tb...@apache.org.
http://git-wip-us.apache.org/repos/asf/ambari/blob/5eb22214/contrib/views/pig/src/main/resources/ui/pig-web/app/controllers/util/pigUtilAlert.js
----------------------------------------------------------------------
diff --git a/contrib/views/pig/src/main/resources/ui/pig-web/app/controllers/util/pigUtilAlert.js b/contrib/views/pig/src/main/resources/ui/pig-web/app/controllers/util/pigUtilAlert.js
new file mode 100644
index 0000000..9a15d3e
--- /dev/null
+++ b/contrib/views/pig/src/main/resources/ui/pig-web/app/controllers/util/pigUtilAlert.js
@@ -0,0 +1,28 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+var App = require('app');
+
+App.PigUtilAlertController = Ember.ArrayController.extend({
+  content:Ember.A(),
+  actions:{
+    removeAlertObject:function (alert) {
+      this.content.removeObject(alert)
+    }
+  },
+});

http://git-wip-us.apache.org/repos/asf/ambari/blob/5eb22214/contrib/views/pig/src/main/resources/ui/pig-web/app/initialize.js
----------------------------------------------------------------------
diff --git a/contrib/views/pig/src/main/resources/ui/pig-web/app/initialize.js b/contrib/views/pig/src/main/resources/ui/pig-web/app/initialize.js
new file mode 100644
index 0000000..0f2424b
--- /dev/null
+++ b/contrib/views/pig/src/main/resources/ui/pig-web/app/initialize.js
@@ -0,0 +1,157 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+var App = require('app');
+
+App.ApplicationAdapter = DS.RESTAdapter.extend({
+  namespace:'api/v1/views/PIG/instances/PIG_1',
+  headers: {
+   'X-Requested-By': 'ambari'
+  }
+});
+
+App.FileAdapter = App.ApplicationAdapter.extend({
+  pathForType: function() {
+    return 'resources/file';
+  }
+});
+
+App.FileSerializer = DS.RESTSerializer.extend({
+  primaryKey:'filePath',
+});
+
+App.IsodateTransform = DS.Transform.extend({  
+  deserialize: function (serialized) {
+    if (serialized) {
+      return moment.unix(serialized).toDate();
+    }
+    return serialized;
+  },
+  serialize: function (deserialized) {
+    if (deserialized) {
+      return moment(deserialized).format('X');
+    }
+    return deserialized;
+  }
+});
+
+Ember.Handlebars.registerBoundHelper('showDate', function(date,format) {
+  return moment(date).format(format)
+});
+
+Em.TextField.reopen(Em.I18n.TranslateableAttributes)
+
+//////////////////////////////////
+// Templates
+//////////////////////////////////
+
+require('translations');
+
+require('templates/application');
+require('templates/index');
+require('templates/pig/loading');
+
+require('templates/pig');
+require('templates/pig/index');
+require('templates/pig/scriptList');
+require('templates/pig/scriptEdit');
+require('templates/pig/scriptEditIndex');
+require('templates/pig/scriptResults');
+require('templates/pig/scriptResultsNav');
+require('templates/pig/job');
+require('templates/pig/jobEdit');
+require('templates/pig/jobStatus');
+require('templates/pig/jobResults');
+require('templates/pig/jobResultsOutput');
+require('templates/pig/history');
+require('templates/pig/udfs');
+
+require('templates/pig/util/script-nav');
+require('templates/pig/util/alert');
+require('templates/pig/util/alert-content');
+require('templates/pig/util/pigHelper');
+require('templates/pig/modal/confirmdelete');
+require('templates/pig/modal/createUdf');
+require('templates/pig/modal/modalLayout');
+require('templates/pig/modal/createScript');
+
+//////////////////////////////////
+// Models
+//////////////////////////////////
+
+require('models/pig_script');
+require('models/pig_job');
+require('models/file');
+require('models/udf');
+
+/////////////////////////////////
+// Controllers
+/////////////////////////////////
+
+require('controllers/pig');
+require('controllers/poll');
+require('controllers/edit');
+require('controllers/pigScriptEdit');
+require('controllers/pigScriptList');
+require('controllers/pigScriptEditResults');
+require('controllers/pigUdfs');
+require('controllers/pigHistory');
+require('controllers/pigJob');
+require('controllers/jobResults');
+require('controllers/util/pigUtilAlert');
+require('controllers/modal/pigModal');
+
+/////////////////////////////////
+// Views
+/////////////////////////////////
+
+require('views/pig');
+require('views/pig/scriptList');
+require('views/pig/scriptEdit');
+require('views/pig/scriptResults');
+require('views/pig/scriptResultsNav');
+require('views/pig/pigHistory');
+require('views/pig/pigUdfs');
+require('views/pig/pigJob');
+require('views/pig/jobResults');
+require('views/pig/modal/pigModal');
+require('views/pig/modal/confirmDelete');
+require('views/pig/modal/createUdf');
+require('views/pig/modal/createScript');
+require('views/pig/util/pigUtilAlert');
+
+/////////////////////////////////
+// Routes
+/////////////////////////////////
+
+require('routes/pig');
+require('routes/pigHistory');
+require('routes/pigIndex');
+require('routes/pigScriptEdit');
+require('routes/pigScriptEditIndex');
+require('routes/pigScriptEditResults');
+require('routes/pigScriptList');
+require('routes/pigUdfs');
+require('routes/pigJob');
+require('routes/jobResults');
+
+/////////////////////////////////
+// Router
+/////////////////////////////////
+
+require('router');

http://git-wip-us.apache.org/repos/asf/ambari/blob/5eb22214/contrib/views/pig/src/main/resources/ui/pig-web/app/models/file.js
----------------------------------------------------------------------
diff --git a/contrib/views/pig/src/main/resources/ui/pig-web/app/models/file.js b/contrib/views/pig/src/main/resources/ui/pig-web/app/models/file.js
new file mode 100644
index 0000000..1c7fa11
--- /dev/null
+++ b/contrib/views/pig/src/main/resources/ui/pig-web/app/models/file.js
@@ -0,0 +1,26 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+var App = require('app');
+
+App.File = DS.Model.extend({
+  fileContent: DS.attr('string'),
+  hasNext:DS.attr('boolean'),
+  page:DS.attr('number'),
+  pageCount:DS.attr('number')
+});

http://git-wip-us.apache.org/repos/asf/ambari/blob/5eb22214/contrib/views/pig/src/main/resources/ui/pig-web/app/models/pig_job.js
----------------------------------------------------------------------
diff --git a/contrib/views/pig/src/main/resources/ui/pig-web/app/models/pig_job.js b/contrib/views/pig/src/main/resources/ui/pig-web/app/models/pig_job.js
new file mode 100644
index 0000000..e4217ae
--- /dev/null
+++ b/contrib/views/pig/src/main/resources/ui/pig-web/app/models/pig_job.js
@@ -0,0 +1,90 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+var App = require('app');
+
+App.Job = DS.Model.extend({
+  pigScript:DS.belongsTo('file', { async: true }),
+  //pythonScript:DS.belongsTo('script'),
+  scriptId: DS.attr('number'),
+  title: DS.attr('string'),
+  templetonArguments:DS.attr('string'),
+  owner: DS.attr('string'),
+  forcedContent:DS.attr('string'),
+
+  sourceFile:DS.attr('string'),
+  sourceFileContent:DS.attr('string'),
+
+  statusDir: DS.attr('string'),
+  status: DS.attr('string'),
+  dateStarted:DS.attr('isodate'),
+  jobId: DS.attr('string'),
+  jobType: DS.attr('string'),
+  percentComplete: DS.attr('number'),
+  percentStatus:function () {
+    if (this.get('isTerminated')) {
+      return 100;
+    };
+    return (this.get('status')==='COMPLETED')?100:(this.get('percentComplete')||0);
+  }.property('status','percentComplete'),
+
+  isTerminated:function(){
+    return (this.get('status')=='KILLED'||this.get('status')=='FAILED');
+  }.property('status'),
+  isKilling:false,
+  kill:function(success,error){
+    var self = this;
+    var host = self.store.adapterFor('application').get('host');
+    var namespace = self.store.adapterFor('application').get('namespace');
+    var url = [host, namespace,'jobs',self.get('id')].join('/');
+
+    self.set('isKilling',true)
+    return Em.$.ajax(url, {
+      type:'DELETE',
+      contentType:'application/json',
+      beforeSend:function(xhr){
+        xhr.setRequestHeader('X-Requested-By','ambari');
+      }
+    }).always(function() {
+      self.set('isKilling',false);
+    }).then(success,error);
+  },
+
+  isExplainJob: function(){
+    return this.jobType == "explain";
+  },
+  isSyntaxCheckJob: function(){
+      return this.jobType == "syntax_check";
+  },
+  isUtilityJob:  function(){
+      return this.isExplainJob() || this.isSyntaxCheckJob();
+  },
+
+  pingStatusMap:{
+    'SUBMITTING':true,
+    'SUBMITTED':true,
+    'RUNNING':true,
+    'COMPLETED':false,
+    'SUBMIT_FAILED':false,
+    'KILLED':false,
+    'FAILED':false
+  },
+  needsPing:function () {
+    return this.pingStatusMap[this.get('status')];
+  }.property('status')
+});

http://git-wip-us.apache.org/repos/asf/ambari/blob/5eb22214/contrib/views/pig/src/main/resources/ui/pig-web/app/models/pig_script.js
----------------------------------------------------------------------
diff --git a/contrib/views/pig/src/main/resources/ui/pig-web/app/models/pig_script.js b/contrib/views/pig/src/main/resources/ui/pig-web/app/models/pig_script.js
new file mode 100644
index 0000000..37b6164
--- /dev/null
+++ b/contrib/views/pig/src/main/resources/ui/pig-web/app/models/pig_script.js
@@ -0,0 +1,43 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+var App = require('app');
+
+App.OpenedScript = Ember.Mixin.create({
+  opened:DS.attr('boolean'),
+  open:function (argument) {
+    return this.set('opened',true);
+  },
+  close:function (argument) {
+    return this.set('opened',false);
+  }
+});
+
+App.Script = DS.Model.extend(App.OpenedScript,{
+  title:DS.attr('string', { defaultValue: 'New script'}),
+  pigScript:DS.belongsTo('file', { async: true }),
+  dateCreated:DS.attr('isodate', { defaultValue: moment()}),
+  templetonArguments:DS.attr('string', { defaultValue: '-useHCatalog'}),
+  // nav item identifier
+  name:function (q){
+    return this.get('title')+this.get('id');
+  }.property('title'),
+  label:function (){
+    return this.get('title');
+  }.property('title')
+});

http://git-wip-us.apache.org/repos/asf/ambari/blob/5eb22214/contrib/views/pig/src/main/resources/ui/pig-web/app/models/udf.js
----------------------------------------------------------------------
diff --git a/contrib/views/pig/src/main/resources/ui/pig-web/app/models/udf.js b/contrib/views/pig/src/main/resources/ui/pig-web/app/models/udf.js
new file mode 100644
index 0000000..6854e2c
--- /dev/null
+++ b/contrib/views/pig/src/main/resources/ui/pig-web/app/models/udf.js
@@ -0,0 +1,25 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+var App = require('app');
+
+App.Udf = DS.Model.extend({
+    path: DS.attr('string'),
+    name: DS.attr('string'),
+    owner: DS.attr('string')
+});

http://git-wip-us.apache.org/repos/asf/ambari/blob/5eb22214/contrib/views/pig/src/main/resources/ui/pig-web/app/router.js
----------------------------------------------------------------------
diff --git a/contrib/views/pig/src/main/resources/ui/pig-web/app/router.js b/contrib/views/pig/src/main/resources/ui/pig-web/app/router.js
new file mode 100644
index 0000000..92b3a3a
--- /dev/null
+++ b/contrib/views/pig/src/main/resources/ui/pig-web/app/router.js
@@ -0,0 +1,37 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+var App = require('app');
+
+App.Router.map(function () {
+  this.resource('pig', { path: "/" }, function() {
+  	this.route('scriptList',{ path: "/list" });
+    this.route('scriptEdit',{ path: "/edit/:script_id" });
+    this.resource('job', { path: "/job/:job_id" },function (argument) {
+      this.route('results');
+    });
+    this.route('udfs');
+  	this.route('history');
+  });
+});
+
+App.LoadingRoute = Ember.Route.extend({});
+
+App.LoadingView = Em.View.extend({
+    templateName: 'pig/loading'
+});

http://git-wip-us.apache.org/repos/asf/ambari/blob/5eb22214/contrib/views/pig/src/main/resources/ui/pig-web/app/routes/jobResults.js
----------------------------------------------------------------------
diff --git a/contrib/views/pig/src/main/resources/ui/pig-web/app/routes/jobResults.js b/contrib/views/pig/src/main/resources/ui/pig-web/app/routes/jobResults.js
new file mode 100644
index 0000000..d01c69a
--- /dev/null
+++ b/contrib/views/pig/src/main/resources/ui/pig-web/app/routes/jobResults.js
@@ -0,0 +1,29 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+var App = require('app');
+
+App.JobResultsRoute = Em.Route.extend({
+  enter: function() {
+      this.controllerFor('pig').set('category',"");
+      this.controllerFor('job').set('category',"results");
+    },
+  model: function (controller) {
+    return this.modelFor('job');
+  }
+});

http://git-wip-us.apache.org/repos/asf/ambari/blob/5eb22214/contrib/views/pig/src/main/resources/ui/pig-web/app/routes/pig.js
----------------------------------------------------------------------
diff --git a/contrib/views/pig/src/main/resources/ui/pig-web/app/routes/pig.js b/contrib/views/pig/src/main/resources/ui/pig-web/app/routes/pig.js
new file mode 100644
index 0000000..71e1d0d
--- /dev/null
+++ b/contrib/views/pig/src/main/resources/ui/pig-web/app/routes/pig.js
@@ -0,0 +1,69 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+var App = require('app');
+
+App.PigRoute = Em.Route.extend({
+  actions: {
+    gotoSection: function(nav) {
+      var location = (nav.hasOwnProperty('url'))?[nav.url]:['pig.scriptEdit',nav.get('id')];
+      this.transitionTo.apply(this,location);
+    },
+    close:function (script) {
+      var self = this;
+      script.close().save().then(function() {
+        if (self.get('controller.category') == script.get('name')) {
+          opened = self.get('controller.openScripts');
+          if (opened.length > 0 && opened.filterBy('id',script.get('id')).length == 0){
+            self.transitionTo('pig.scriptEdit',opened.get(0));
+          } else {
+            self.transitionTo('pig.scriptList');
+          }
+        }
+        self.send('showAlert', {'message':Em.I18n.t('scripts.alert.script_saved',{title: script.get('title')}), status:'success'});
+      },function (error) {
+        //script.open();
+        self.send('showAlert', {'message': Em.I18n.t('scripts.alert.save_error_reason',{message:error.statusText}) , status:'error'});
+      });
+    },
+    showAlert:function (alert) {
+      var pigUtilAlert = this.controllerFor('pigUtilAlert');
+      return pigUtilAlert.content.pushObject(Em.Object.create(alert));
+    },
+    openModal: function(modalName,controller) {
+      return this.render(modalName, {
+        into: 'pig',
+        outlet: 'modal',
+        controller:'pigModal'
+      });
+    },
+    closeModal: function() {
+      return this.disconnectOutlet({
+        outlet: 'modal',
+        parentView: 'pig'
+      });
+    }
+  },
+  model: function() {
+    return this.store.find('script');
+  },
+  renderTemplate: function() {
+    this.render('pig');
+    this.render('pig/util/alert', {into:'pig',outlet:'alert',controller: 'pigUtilAlert' });
+  }
+});

http://git-wip-us.apache.org/repos/asf/ambari/blob/5eb22214/contrib/views/pig/src/main/resources/ui/pig-web/app/routes/pigHistory.js
----------------------------------------------------------------------
diff --git a/contrib/views/pig/src/main/resources/ui/pig-web/app/routes/pigHistory.js b/contrib/views/pig/src/main/resources/ui/pig-web/app/routes/pigHistory.js
new file mode 100644
index 0000000..cf9e3d5
--- /dev/null
+++ b/contrib/views/pig/src/main/resources/ui/pig-web/app/routes/pigHistory.js
@@ -0,0 +1,28 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+var App = require('app');
+
+App.PigHistoryRoute = Em.Route.extend({
+  enter: function() {
+    this.controllerFor('pig').set('category',"history");
+  },
+  model: function() {
+    return this.store.find('job');
+  }
+});

http://git-wip-us.apache.org/repos/asf/ambari/blob/5eb22214/contrib/views/pig/src/main/resources/ui/pig-web/app/routes/pigIndex.js
----------------------------------------------------------------------
diff --git a/contrib/views/pig/src/main/resources/ui/pig-web/app/routes/pigIndex.js b/contrib/views/pig/src/main/resources/ui/pig-web/app/routes/pigIndex.js
new file mode 100644
index 0000000..04e04dd
--- /dev/null
+++ b/contrib/views/pig/src/main/resources/ui/pig-web/app/routes/pigIndex.js
@@ -0,0 +1,25 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+var App = require('app');
+
+App.PigIndexRoute = Em.Route.extend({
+  beforeModel: function() {
+    this.transitionTo('pig.scriptList');
+  }
+});

http://git-wip-us.apache.org/repos/asf/ambari/blob/5eb22214/contrib/views/pig/src/main/resources/ui/pig-web/app/routes/pigJob.js
----------------------------------------------------------------------
diff --git a/contrib/views/pig/src/main/resources/ui/pig-web/app/routes/pigJob.js b/contrib/views/pig/src/main/resources/ui/pig-web/app/routes/pigJob.js
new file mode 100644
index 0000000..5f8a0ba
--- /dev/null
+++ b/contrib/views/pig/src/main/resources/ui/pig-web/app/routes/pigJob.js
@@ -0,0 +1,54 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+var App = require('app');
+
+App.JobRoute = Em.Route.extend({
+    actions: {
+      error: function(error, transition) {
+        Em.warn(error.stack);
+        transition.send('showAlert', {'message':Em.I18n.t('job.alert.load_error',{message:error.message}), status:'error'});
+        this.transitionTo('pig.scriptList');
+      },
+      navigate:function (argument) {
+        return this.transitionTo(argument.route)
+      }
+    },
+    setupController: function(controller, model) {
+      controller.set('model', model);
+      this.controllerFor('poll').set('model', model);
+    },
+    afterModel:function (job,arg) {
+      this.controllerFor('poll').get('pollster').start(job);
+    },
+    deactivate: function() {
+      this.controllerFor('poll').get('pollster').stop();
+    },
+    renderTemplate: function() {
+      this.render('pig/scriptEdit', {controller: 'job' });
+      this.render('pig/job', {into:'pig/scriptEdit',outlet: 'main', controller: 'poll' });
+      this.render('pig/scriptResultsNav',{into:'pig/scriptEdit',outlet: 'nav'});
+    }
+});
+
+App.JobIndexRoute = Em.Route.extend({
+  enter: function() {
+      this.controllerFor('pig').set('category',"");
+      this.controllerFor('job').set('category',"edit");
+    },
+});

http://git-wip-us.apache.org/repos/asf/ambari/blob/5eb22214/contrib/views/pig/src/main/resources/ui/pig-web/app/routes/pigScriptEdit.js
----------------------------------------------------------------------
diff --git a/contrib/views/pig/src/main/resources/ui/pig-web/app/routes/pigScriptEdit.js b/contrib/views/pig/src/main/resources/ui/pig-web/app/routes/pigScriptEdit.js
new file mode 100644
index 0000000..a31864f
--- /dev/null
+++ b/contrib/views/pig/src/main/resources/ui/pig-web/app/routes/pigScriptEdit.js
@@ -0,0 +1,71 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+var App = require('app');
+
+App.PigScriptEditRoute = Em.Route.extend({
+  actions:{
+    willTransition: function(transition){
+      var model = this.controller.get('model');
+      if (model.get('isDirty') || model.get('pigScript.isDirty')) {
+        return this.send('saveScript',model);
+      };
+    },
+    toresults:function (argument) {
+      // DUMMY TRANSITION
+      this.transitionTo('pigScriptEdit.results',argument);
+    },
+    saveScript: function (script) {
+      var router = this,
+        onSuccess = function(model){
+          router.send('showAlert', {'message':Em.I18n.t('scripts.alert.script_saved',{title: script.get('title')}),status:'success'});
+        },
+        onFail = function(error){
+          router.send('showAlert', {'message':Em.I18n.t('scripts.alert.save_error'),status:'error'});
+        };
+
+      return script.get('pigScript').then(function(file){
+        return Ember.RSVP.all([file.save(),script.save()]).then(onSuccess,onFail);
+      },onFail);
+    },
+  },
+  isExec:false,
+  model: function(params) {
+    var record;
+    var isExist = this.store.all('script').some(function(script) {
+      return script.get('id') === params.script_id;
+    });
+    if (isExist) { 
+      record = this.store.find('script',params.script_id);
+    } else {
+      record = this.store.createRecord('script');
+    }
+    return record;
+  },
+  afterModel:function  (model) {
+    if (model.get('length') == 0) {
+      this.transitionTo('pig');
+    }
+    this.controllerFor('pig').set('category', model.get('name'));
+    model.open();
+  },
+  renderTemplate: function() {
+    this.render('pig/scriptEdit');
+  }
+});
+

http://git-wip-us.apache.org/repos/asf/ambari/blob/5eb22214/contrib/views/pig/src/main/resources/ui/pig-web/app/routes/pigScriptEditIndex.js
----------------------------------------------------------------------
diff --git a/contrib/views/pig/src/main/resources/ui/pig-web/app/routes/pigScriptEditIndex.js b/contrib/views/pig/src/main/resources/ui/pig-web/app/routes/pigScriptEditIndex.js
new file mode 100644
index 0000000..638ebe8
--- /dev/null
+++ b/contrib/views/pig/src/main/resources/ui/pig-web/app/routes/pigScriptEditIndex.js
@@ -0,0 +1,27 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+var App = require('app');
+
+App.PigScriptEditIndexRoute = Em.Route.extend({
+  renderTemplate: function() {
+    this.render('pig/scriptEditIndex',{
+      outlet: 'main',
+    });
+  }
+});

http://git-wip-us.apache.org/repos/asf/ambari/blob/5eb22214/contrib/views/pig/src/main/resources/ui/pig-web/app/routes/pigScriptEditResults.js
----------------------------------------------------------------------
diff --git a/contrib/views/pig/src/main/resources/ui/pig-web/app/routes/pigScriptEditResults.js b/contrib/views/pig/src/main/resources/ui/pig-web/app/routes/pigScriptEditResults.js
new file mode 100644
index 0000000..1a77e71
--- /dev/null
+++ b/contrib/views/pig/src/main/resources/ui/pig-web/app/routes/pigScriptEditResults.js
@@ -0,0 +1,36 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+var App = require('app');
+
+App.PigScriptEditResultsRoute = Em.Route.extend({
+  model: function(params) {
+    return this.store.find('job',params.job_id);
+  },
+  afterModel:function (model) {
+    //this.controllerFor('pigScriptEdit').set('activeJob',model);
+  },
+  renderTemplate: function() {
+    this.render('pig/scriptResultsNav',{
+      outlet: 'nav',
+    });
+    this.render('pig/scriptResults',{
+      outlet: 'main',
+    });
+  }
+});

http://git-wip-us.apache.org/repos/asf/ambari/blob/5eb22214/contrib/views/pig/src/main/resources/ui/pig-web/app/routes/pigScriptList.js
----------------------------------------------------------------------
diff --git a/contrib/views/pig/src/main/resources/ui/pig-web/app/routes/pigScriptList.js b/contrib/views/pig/src/main/resources/ui/pig-web/app/routes/pigScriptList.js
new file mode 100644
index 0000000..20c0fe9
--- /dev/null
+++ b/contrib/views/pig/src/main/resources/ui/pig-web/app/routes/pigScriptList.js
@@ -0,0 +1,88 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+var App = require('app');
+
+App.PigScriptListRoute = Em.Route.extend({
+  actions:{
+    createScript:function () {
+      var newScript = this.store.createRecord('script');
+      this.controllerFor('pigModal').set('content', newScript);
+      return this.send('openModal','createScript');
+      
+    },
+    deletescript:function (script) {
+      this.controllerFor('pigModal').set('content', script);
+      return this.send('openModal','confirmDelete');
+    },
+    confirmcreate:function (script,filePath) {
+      // /tmp/.pigscripts/admin/39.pig
+      var route = this;
+      var sendAlert = function (status) {
+        var alerts = {
+          success:Em.I18n.t('scripts.alert.script_created',{title:'New script'}), 
+          error: Em.I18n.t('scripts.alert.create_failed')
+        };
+        return function () {
+          if (status=='error'){
+            script.deleteRecord();
+          }
+          route.send('showAlert', {message:alerts[status],status:status});
+        };
+      };
+      if (filePath) {
+        var file = this.store.createRecord('file',{
+          id:filePath,
+          fileContent:''
+        });
+        return file.save().then(function(file){
+          script.set('pigScript',file);
+          script.save().then(sendAlert('success'),sendAlert('error'));
+        },function () {
+          file.deleteRecord();
+          route.store.find('file', filePath).then(function(file) {
+            route.send('showAlert', {message:Em.I18n.t('scripts.alert.file_exist_error'),status:'success'});
+            script.set('pigScript',file);
+            script.save().then(sendAlert('success'),sendAlert('error'));
+          }, sendAlert('error'));
+        });
+      } else {
+          script.save().then(sendAlert('success'),sendAlert('error'));
+      }
+
+
+    },
+    confirmdelete:function (script) {
+      var router = this;
+      var onSuccess = function(model){
+            router.send('showAlert', {'message':Em.I18n.t('scripts.alert.script_deleted',{title : model.get('title')}),status:'success'});
+          };
+      var onFail = function(error){
+            router.send('showAlert', {'message':Em.I18n.t('scripts.alert.delete_failed'),status:'error'});
+          };
+      script.deleteRecord();
+      return script.save().then(onSuccess,onFail);
+    }
+  },
+  enter: function() {
+    this.controllerFor('pig').set('category',"scripts");
+  },
+  model: function(object,transition) {
+    return this.modelFor('pig');
+  }
+});

http://git-wip-us.apache.org/repos/asf/ambari/blob/5eb22214/contrib/views/pig/src/main/resources/ui/pig-web/app/routes/pigUdfs.js
----------------------------------------------------------------------
diff --git a/contrib/views/pig/src/main/resources/ui/pig-web/app/routes/pigUdfs.js b/contrib/views/pig/src/main/resources/ui/pig-web/app/routes/pigUdfs.js
new file mode 100644
index 0000000..42e4223
--- /dev/null
+++ b/contrib/views/pig/src/main/resources/ui/pig-web/app/routes/pigUdfs.js
@@ -0,0 +1,55 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+var App = require('app');
+
+App.PigUdfsRoute = Em.Route.extend({
+  actions:{
+    createUdfModal:function () {
+      this.controllerFor('pigModal').set('content', this.store.createRecord('udf'));
+      return this.send('openModal','createUdf');
+    },
+    createUdf:function (udf) {
+      var router = this;
+      var onSuccess = function(model){
+          router.send('showAlert', {'message': Em.I18n.t('udfs.alert.udf_created',{name : model.get('name')}), status:'success'});
+        };
+      var onFail = function(error){
+          router.send('showAlert', {'message':Em.I18n.t('udfs.alert.create_failed'),status:'error'});
+        };
+      return udf.save().then(onSuccess,onFail);
+    },
+    deleteUdf:function(udf){
+      var router = this;
+      var onSuccess = function(model){
+            router.send('showAlert', {'message': Em.I18n.t('udfs.alert.udf_deleted',{name : model.get('name')}),status:'success'});
+          };
+      var onFail = function(error){
+            router.send('showAlert', {'message': Em.I18n.t('udfs.alert.delete_failed'),status:'error'});
+          };
+      udf.deleteRecord();
+      return udf.save().then(onSuccess,onFail);
+    }
+  },
+  enter: function() {
+    this.controllerFor('pig').set('category',"udfs");
+  },
+  model: function() {
+    return this.store.find('udf');
+  }
+});

http://git-wip-us.apache.org/repos/asf/ambari/blob/5eb22214/contrib/views/pig/src/main/resources/ui/pig-web/app/styles/style.less
----------------------------------------------------------------------
diff --git a/contrib/views/pig/src/main/resources/ui/pig-web/app/styles/style.less b/contrib/views/pig/src/main/resources/ui/pig-web/app/styles/style.less
new file mode 100644
index 0000000..9871a9a
--- /dev/null
+++ b/contrib/views/pig/src/main/resources/ui/pig-web/app/styles/style.less
@@ -0,0 +1,295 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+.wrap {
+	padding: 15px;
+}
+.moz-padding (@selector, @pre: ~'', @padding) {
+  @-moz-document url-prefix() {
+    @{pre}@{selector} {
+      padding: @padding !important;
+    }
+  }
+}
+
+.base-shadow (@shadow) {
+  -webkit-box-shadow: @shadow;
+     -moz-box-shadow: @shadow;
+          box-shadow: @shadow;
+}
+
+.base-transition (@transition) {
+  -webkit-transition: @transition;
+  -moz-transition: @transition;
+  -o-transition: @transition;
+  -ms-transition: @transition;
+  transition: @transition;
+}
+
+.common-shadow {
+  .base-shadow(0 5px 10px rgba(0, 0, 0, 0.2));
+}
+
+.common-shadow-inset {
+  .base-shadow(inset 0 1px 1px rgba(0, 0, 0, 0.05));
+}
+
+// navigation
+.navigation {
+  //position: fixed;
+  a {
+    cursor: pointer;
+  }
+  .pig-nav-item {
+    word-break: break-word;
+    .rm {
+      top:2px;
+      position: absolute;
+      right: 5px;
+      top: 5px;
+    }
+  }
+}
+
+//script list
+.panel-scriptlist {
+  .new-script {
+    position: relative;
+    top:-5px;
+  }
+}
+
+//udfs
+.panel-udfs {
+  .upload-udf {
+    position: relative;
+    top:-5px;
+  }
+}
+
+//edit script
+.edit-script {
+  .panel-editscript {
+    textarea {
+      width: 100%;
+      max-width: 100%;
+      height: 300px;
+    }
+    div > textarea{
+      padding-right: 10px;
+    }
+    .inactive {
+      opacity: 0.2;
+    }
+    .CodeMirror {
+      .common-shadow-inset;
+
+    }
+    .panel-heading{
+      #title {
+        display: inline-block;
+        width: auto;
+      }
+      .nav-results > li > a {
+        padding: 7px 15px;
+      }
+    }
+    .panel-body {
+      padding: 5px; 
+      background-color: #f5f5f5; 
+      border-bottom: 1px solid #dddddd;
+      .argadd {
+        font-size: 13px;
+        width:10%;
+        display: inline-block;
+        height:22px;
+        padding: 0 5px;
+      }
+      .editable{
+        background-color: #428bca !important;
+      }
+      .argument {
+        vertical-align: middle;
+        background-color: #999999;
+        display: inline-block;
+        font-size: 75%;
+        font-weight: bold;
+        line-height: 1;
+        color: #ffffff;
+        text-align: center;
+        white-space: nowrap;
+        border-radius: .3em;
+        height: 22px;
+        .title {
+          float: left;
+          padding: 7px;
+        }
+        .moz-padding(rm-arg, ~'.',0 5px 0 0);
+        .rm-arg {
+          position: relative;
+          padding: 2px 5px 0 0;
+        }
+      }
+    }
+  }
+  .pigParams {
+    padding-bottom: 10px; 
+  }
+}
+
+.job-status-view {
+  .progress {
+    margin-bottom: 0;
+  }
+  .kill-button {
+    float: left; 
+    margin-right: 10px;
+  }
+}
+
+//utils
+#alert-wrap {
+  position: fixed;
+  bottom: 0;
+  width: 16.666666666666664%;
+  padding-right: 30px;
+  font-size: 0.9em;
+  
+  .alert {
+    .common-shadow;
+  }
+}
+
+.spinner (@border, @size) {
+  //display: inline-block;
+  border: @border;
+  font-size: @size;
+  width: 1em;
+  height: 1em;
+  border-radius: .5em;
+  -moz-box-sizing: border-box;
+  -webkit-box-sizing: border-box;
+  box-sizing: border-box;
+  -webkit-animation: spin 1s linear infinite;
+  -moz-animation: spin 1s linear infinite;
+  animation: spin 1s linear infinite;
+  border-top-color: black;
+}
+
+.spinner-sm {
+  .spinner(2px solid #eeeeee, 20px);
+}
+
+.spinner-bg {
+  .spinner(6px solid #eeeeee, 60px);
+}
+
+.editor-container {
+  position: relative;
+}
+
+.edit-confirm-container {
+  display: inline-block;
+  margin-top: 20px;
+}
+
+.edit-confirm {
+  height: 100%;
+  width: 100%;
+  position: absolute;
+  z-index: 1000;
+  text-align: center;
+}
+
+
+@-webkit-keyframes spin {
+  to {
+    -moz-transform: rotate(360deg);
+    -ms-transform: rotate(360deg);
+    -webkit-transform: rotate(360deg);
+    transform: rotate(360deg);
+  }
+}
+@-moz-keyframes spin {
+  to {
+    -moz-transform: rotate(360deg);
+    -ms-transform: rotate(360deg);
+    -webkit-transform: rotate(360deg);
+    transform: rotate(360deg);
+  }
+}
+@keyframes spin {
+  to {
+    -moz-transform: rotate(360deg);
+    -ms-transform: rotate(360deg);
+    -webkit-transform: rotate(360deg);
+    transform: rotate(360deg);
+  }
+}
+
+.dropdown-submenu {
+  position:relative;
+}
+.dropdown-submenu > .dropdown-menu {
+  top:0;
+  left:100%;
+  margin-top:-6px;
+  margin-left:-1px;
+  -webkit-border-radius:0 6px 6px 6px;
+  -moz-border-radius:0 6px 6px 6px;
+  border-radius:0 6px 6px 6px;
+}
+.dropdown-submenu:hover > .dropdown-menu {
+  display:block;
+}
+.dropdown-submenu > a:after {
+  display:block;
+  content:" ";
+  float:right;
+  width:0;
+  height:0;
+  border-color:transparent;
+  border-style:solid;
+  border-width:5px 0 5px 5px;
+  border-left-color:#cccccc;
+  margin-top:5px;
+  margin-right:-10px;
+}
+.dropdown-submenu:hover > a:after {
+  border-left-color:#ffffff;
+}
+.dropdown-submenu.pull-left {
+  float:none;
+}
+.dropdown-submenu.pull-left > .dropdown-menu {
+  left:-100%;
+  margin-left:10px;
+  -webkit-border-radius:6px 0 6px 6px;
+  -moz-border-radius:6px 0 6px 6px;
+  border-radius:6px 0 6px 6px;
+}
+
+
+a.list-group-item.active{
+  z-index: 2;
+  color: #ffffff;
+  background-color: #428bca;
+  border-color: #428bca;
+  .base-transition(border-color 200ms linear, background-color 200ms linear;);
+}
+

http://git-wip-us.apache.org/repos/asf/ambari/blob/5eb22214/contrib/views/pig/src/main/resources/ui/pig-web/app/templates/application.hbs
----------------------------------------------------------------------
diff --git a/contrib/views/pig/src/main/resources/ui/pig-web/app/templates/application.hbs b/contrib/views/pig/src/main/resources/ui/pig-web/app/templates/application.hbs
new file mode 100644
index 0000000..a87c2a7
--- /dev/null
+++ b/contrib/views/pig/src/main/resources/ui/pig-web/app/templates/application.hbs
@@ -0,0 +1,21 @@
+{{!
+   Licensed to the Apache Software Foundation (ASF) under one
+   or more contributor license agreements.  See the NOTICE file
+   distributed with this work for additional information
+   regarding copyright ownership.  The ASF licenses this file
+   to you under the Apache License, Version 2.0 (the
+   "License"); you may not use this file except in compliance
+   with the License.  You may obtain a copy of the License at
+  
+       http://www.apache.org/licenses/LICENSE-2.0
+  
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.
+}}
+
+<div class="wrap">
+	{{outlet}}
+</div>

http://git-wip-us.apache.org/repos/asf/ambari/blob/5eb22214/contrib/views/pig/src/main/resources/ui/pig-web/app/templates/index.hbs
----------------------------------------------------------------------
diff --git a/contrib/views/pig/src/main/resources/ui/pig-web/app/templates/index.hbs b/contrib/views/pig/src/main/resources/ui/pig-web/app/templates/index.hbs
new file mode 100644
index 0000000..0efb5b2
--- /dev/null
+++ b/contrib/views/pig/src/main/resources/ui/pig-web/app/templates/index.hbs
@@ -0,0 +1,18 @@
+{{!
+   Licensed to the Apache Software Foundation (ASF) under one
+   or more contributor license agreements.  See the NOTICE file
+   distributed with this work for additional information
+   regarding copyright ownership.  The ASF licenses this file
+   to you under the Apache License, Version 2.0 (the
+   "License"); you may not use this file except in compliance
+   with the License.  You may obtain a copy of the License at
+  
+       http://www.apache.org/licenses/LICENSE-2.0
+  
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.
+}}
+

http://git-wip-us.apache.org/repos/asf/ambari/blob/5eb22214/contrib/views/pig/src/main/resources/ui/pig-web/app/templates/loading.hbs
----------------------------------------------------------------------
diff --git a/contrib/views/pig/src/main/resources/ui/pig-web/app/templates/loading.hbs b/contrib/views/pig/src/main/resources/ui/pig-web/app/templates/loading.hbs
new file mode 100644
index 0000000..8017bcf
--- /dev/null
+++ b/contrib/views/pig/src/main/resources/ui/pig-web/app/templates/loading.hbs
@@ -0,0 +1,19 @@
+{{!
+   Licensed to the Apache Software Foundation (ASF) under one
+   or more contributor license agreements.  See the NOTICE file
+   distributed with this work for additional information
+   regarding copyright ownership.  The ASF licenses this file
+   to you under the Apache License, Version 2.0 (the
+   "License"); you may not use this file except in compliance
+   with the License.  You may obtain a copy of the License at
+  
+       http://www.apache.org/licenses/LICENSE-2.0
+  
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.
+}}
+
+<div class="spinner spinner-bg"></div>

http://git-wip-us.apache.org/repos/asf/ambari/blob/5eb22214/contrib/views/pig/src/main/resources/ui/pig-web/app/templates/pig.hbs
----------------------------------------------------------------------
diff --git a/contrib/views/pig/src/main/resources/ui/pig-web/app/templates/pig.hbs b/contrib/views/pig/src/main/resources/ui/pig-web/app/templates/pig.hbs
new file mode 100644
index 0000000..70e87ae
--- /dev/null
+++ b/contrib/views/pig/src/main/resources/ui/pig-web/app/templates/pig.hbs
@@ -0,0 +1,31 @@
+{{!
+   Licensed to the Apache Software Foundation (ASF) under one
+   or more contributor license agreements.  See the NOTICE file
+   distributed with this work for additional information
+   regarding copyright ownership.  The ASF licenses this file
+   to you under the Apache License, Version 2.0 (the
+   "License"); you may not use this file except in compliance
+   with the License.  You may obtain a copy of the License at
+  
+       http://www.apache.org/licenses/LICENSE-2.0
+  
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.
+}}
+
+<div class="container-fluid">
+  <div class="row">
+    <div class="col-md-2 navigation">
+      {{view view.navItemsView}}
+      {{outlet alert}}
+    </div>
+    <div class="col-md-10">
+      {{outlet}}
+    </div>
+  </div>
+</div>
+
+{{outlet modal}}

http://git-wip-us.apache.org/repos/asf/ambari/blob/5eb22214/contrib/views/pig/src/main/resources/ui/pig-web/app/templates/pig/history.hbs
----------------------------------------------------------------------
diff --git a/contrib/views/pig/src/main/resources/ui/pig-web/app/templates/pig/history.hbs b/contrib/views/pig/src/main/resources/ui/pig-web/app/templates/pig/history.hbs
new file mode 100644
index 0000000..a1d5aae
--- /dev/null
+++ b/contrib/views/pig/src/main/resources/ui/pig-web/app/templates/pig/history.hbs
@@ -0,0 +1,46 @@
+{{!
+   Licensed to the Apache Software Foundation (ASF) under one
+   or more contributor license agreements.  See the NOTICE file
+   distributed with this work for additional information
+   regarding copyright ownership.  The ASF licenses this file
+   to you under the Apache License, Version 2.0 (the
+   "License"); you may not use this file except in compliance
+   with the License.  You may obtain a copy of the License at
+  
+       http://www.apache.org/licenses/LICENSE-2.0
+  
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.
+}}
+
+<div class="panel panel-default panel-history">
+  <div class="panel-heading">
+    {{t 'common.history'}}
+  </div>
+  
+  <table class="table table-bordered table-striped ">
+    <thead> 
+      <tr class="label-row">
+        <th class="first">{{t 'job.title'}}</th> 
+        <th>{{t 'job.started'}}</th> 
+        <th>{{t 'job.status'}}</th> 
+        <th></th> 
+      </tr>
+    </thead>
+    <tbody> 
+    {{#each jobs}}
+      {{#view view.historyTableRow}}
+        <tr> 
+          <td class="first">{{#link-to 'job' this.id }} {{this.title}}{{/link-to}}</td>
+          <td><span class="date">{{showDate this.dateStarted 'YYYY-MM-DD HH:mm'}}</span></td>
+          <td><span {{bind-attr class=":label view.labelClass"}}>{{this.status}}</span></td>
+          <td>{{#link-to 'job.results' this.id }} {{t 'job.results'}} {{/link-to}}</td>
+        </tr>
+      {{/view}}
+    {{/each}}
+    </tbody>
+  </table>
+</div>

http://git-wip-us.apache.org/repos/asf/ambari/blob/5eb22214/contrib/views/pig/src/main/resources/ui/pig-web/app/templates/pig/index.hbs
----------------------------------------------------------------------
diff --git a/contrib/views/pig/src/main/resources/ui/pig-web/app/templates/pig/index.hbs b/contrib/views/pig/src/main/resources/ui/pig-web/app/templates/pig/index.hbs
new file mode 100644
index 0000000..e3cbb1e
--- /dev/null
+++ b/contrib/views/pig/src/main/resources/ui/pig-web/app/templates/pig/index.hbs
@@ -0,0 +1,19 @@
+{{!
+   Licensed to the Apache Software Foundation (ASF) under one
+   or more contributor license agreements.  See the NOTICE file
+   distributed with this work for additional information
+   regarding copyright ownership.  The ASF licenses this file
+   to you under the Apache License, Version 2.0 (the
+   "License"); you may not use this file except in compliance
+   with the License.  You may obtain a copy of the License at
+  
+       http://www.apache.org/licenses/LICENSE-2.0
+  
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.
+}}
+
+

http://git-wip-us.apache.org/repos/asf/ambari/blob/5eb22214/contrib/views/pig/src/main/resources/ui/pig-web/app/templates/pig/job.hbs
----------------------------------------------------------------------
diff --git a/contrib/views/pig/src/main/resources/ui/pig-web/app/templates/pig/job.hbs b/contrib/views/pig/src/main/resources/ui/pig-web/app/templates/pig/job.hbs
new file mode 100644
index 0000000..ed81a68
--- /dev/null
+++ b/contrib/views/pig/src/main/resources/ui/pig-web/app/templates/pig/job.hbs
@@ -0,0 +1,39 @@
+{{!
+   Licensed to the Apache Software Foundation (ASF) under one
+   or more contributor license agreements.  See the NOTICE file
+   distributed with this work for additional information
+   regarding copyright ownership.  The ASF licenses this file
+   to you under the Apache License, Version 2.0 (the
+   "License"); you may not use this file except in compliance
+   with the License.  You may obtain a copy of the License at
+  
+       http://www.apache.org/licenses/LICENSE-2.0
+  
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.
+}}
+
+<div class="well well-sm">
+  <div class="jobStatus" style="margin-bottom: 5px;">
+    <small>
+    {{t 'job.job_status'}} <strong>{{content.status}}</strong>
+    </small>
+  </div>
+
+  {{#if content.needsPing}}
+    {{#unless content.isKilling}}
+      <button {{action "killjob" content}} type="button" class="btn btn-danger btn-xs kill-button">Kill</button>
+    {{/unless}}
+    {{#if content.isKilling}}
+      <div class="spinner-sm pull-left kill-button"></div>
+    {{/if}}
+  {{/if}}
+
+  {{view view.progressBar contentBinding="content"}}
+</div>
+
+
+{{outlet}}

http://git-wip-us.apache.org/repos/asf/ambari/blob/5eb22214/contrib/views/pig/src/main/resources/ui/pig-web/app/templates/pig/jobEdit.hbs
----------------------------------------------------------------------
diff --git a/contrib/views/pig/src/main/resources/ui/pig-web/app/templates/pig/jobEdit.hbs b/contrib/views/pig/src/main/resources/ui/pig-web/app/templates/pig/jobEdit.hbs
new file mode 100644
index 0000000..0efb5b2
--- /dev/null
+++ b/contrib/views/pig/src/main/resources/ui/pig-web/app/templates/pig/jobEdit.hbs
@@ -0,0 +1,18 @@
+{{!
+   Licensed to the Apache Software Foundation (ASF) under one
+   or more contributor license agreements.  See the NOTICE file
+   distributed with this work for additional information
+   regarding copyright ownership.  The ASF licenses this file
+   to you under the Apache License, Version 2.0 (the
+   "License"); you may not use this file except in compliance
+   with the License.  You may obtain a copy of the License at
+  
+       http://www.apache.org/licenses/LICENSE-2.0
+  
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.
+}}
+

http://git-wip-us.apache.org/repos/asf/ambari/blob/5eb22214/contrib/views/pig/src/main/resources/ui/pig-web/app/templates/pig/jobResults.hbs
----------------------------------------------------------------------
diff --git a/contrib/views/pig/src/main/resources/ui/pig-web/app/templates/pig/jobResults.hbs b/contrib/views/pig/src/main/resources/ui/pig-web/app/templates/pig/jobResults.hbs
new file mode 100644
index 0000000..67c49bd
--- /dev/null
+++ b/contrib/views/pig/src/main/resources/ui/pig-web/app/templates/pig/jobResults.hbs
@@ -0,0 +1,19 @@
+{{!
+   Licensed to the Apache Software Foundation (ASF) under one
+   or more contributor license agreements.  See the NOTICE file
+   distributed with this work for additional information
+   regarding copyright ownership.  The ASF licenses this file
+   to you under the Apache License, Version 2.0 (the
+   "License"); you may not use this file except in compliance
+   with the License.  You may obtain a copy of the License at
+  
+       http://www.apache.org/licenses/LICENSE-2.0
+  
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.
+}}
+
+{{view view.outputView}}

http://git-wip-us.apache.org/repos/asf/ambari/blob/5eb22214/contrib/views/pig/src/main/resources/ui/pig-web/app/templates/pig/jobResultsOutput.hbs
----------------------------------------------------------------------
diff --git a/contrib/views/pig/src/main/resources/ui/pig-web/app/templates/pig/jobResultsOutput.hbs b/contrib/views/pig/src/main/resources/ui/pig-web/app/templates/pig/jobResultsOutput.hbs
new file mode 100644
index 0000000..947b973
--- /dev/null
+++ b/contrib/views/pig/src/main/resources/ui/pig-web/app/templates/pig/jobResultsOutput.hbs
@@ -0,0 +1,40 @@
+{{!
+   Licensed to the Apache Software Foundation (ASF) under one
+   or more contributor license agreements.  See the NOTICE file
+   distributed with this work for additional information
+   regarding copyright ownership.  The ASF licenses this file
+   to you under the Apache License, Version 2.0 (the
+   "License"); you may not use this file except in compliance
+   with the License.  You may obtain a copy of the License at
+  
+       http://www.apache.org/licenses/LICENSE-2.0
+  
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.
+}}
+
+<div class="panel-heading">
+  <div class="btn-group" data-toggle="buttons" >
+    <label id='btn-stdout' {{action 'getOutput' 'stdout' target="view"}} {{bind-attr class=":btn :btn-success view.isLoadingOutput:disabled:" }} >
+      <input type="radio" name="options"> {{t  'job.job_results.stdout'}}
+    </label>
+    <label id='btn-stderr' {{action 'getOutput' 'stderr' target="view"}} {{bind-attr class=":btn :btn-danger view.isLoadingOutput:disabled:" }}>
+      <input type="radio" name="options"> {{t  'job.job_results.stderr'}}
+    </label>
+    <label id='btn-exitcode' {{action 'getOutput' 'exitcode' target="view"}} {{bind-attr class=":btn :btn-default view.isLoadingOutput:disabled:" }}>
+      <input type="radio" name="options"> {{t  'job.job_results.exitcode'}}
+    </label>
+  </div>
+</div>
+<div class="panel-body">
+
+  {{#unless view.isLoadingOutput}}
+    <pre>{{view.activeOutput}}</pre>
+  {{/unless}}
+  {{#if view.isLoadingOutput}}
+    <div class="spinner-sm"></div>
+  {{/if}}
+</div>

http://git-wip-us.apache.org/repos/asf/ambari/blob/5eb22214/contrib/views/pig/src/main/resources/ui/pig-web/app/templates/pig/jobStatus.hbs
----------------------------------------------------------------------
diff --git a/contrib/views/pig/src/main/resources/ui/pig-web/app/templates/pig/jobStatus.hbs b/contrib/views/pig/src/main/resources/ui/pig-web/app/templates/pig/jobStatus.hbs
new file mode 100644
index 0000000..0efb5b2
--- /dev/null
+++ b/contrib/views/pig/src/main/resources/ui/pig-web/app/templates/pig/jobStatus.hbs
@@ -0,0 +1,18 @@
+{{!
+   Licensed to the Apache Software Foundation (ASF) under one
+   or more contributor license agreements.  See the NOTICE file
+   distributed with this work for additional information
+   regarding copyright ownership.  The ASF licenses this file
+   to you under the Apache License, Version 2.0 (the
+   "License"); you may not use this file except in compliance
+   with the License.  You may obtain a copy of the License at
+  
+       http://www.apache.org/licenses/LICENSE-2.0
+  
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.
+}}
+

http://git-wip-us.apache.org/repos/asf/ambari/blob/5eb22214/contrib/views/pig/src/main/resources/ui/pig-web/app/templates/pig/loading.hbs
----------------------------------------------------------------------
diff --git a/contrib/views/pig/src/main/resources/ui/pig-web/app/templates/pig/loading.hbs b/contrib/views/pig/src/main/resources/ui/pig-web/app/templates/pig/loading.hbs
new file mode 100644
index 0000000..d677772
--- /dev/null
+++ b/contrib/views/pig/src/main/resources/ui/pig-web/app/templates/pig/loading.hbs
@@ -0,0 +1,20 @@
+{{!
+   Licensed to the Apache Software Foundation (ASF) under one
+   or more contributor license agreements.  See the NOTICE file
+   distributed with this work for additional information
+   regarding copyright ownership.  The ASF licenses this file
+   to you under the Apache License, Version 2.0 (the
+   "License"); you may not use this file except in compliance
+   with the License.  You may obtain a copy of the License at
+  
+       http://www.apache.org/licenses/LICENSE-2.0
+  
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.
+}}
+
+
+<div class="spinner-bg center-block"></div>

http://git-wip-us.apache.org/repos/asf/ambari/blob/5eb22214/contrib/views/pig/src/main/resources/ui/pig-web/app/templates/pig/modal/confirmdelete.hbs
----------------------------------------------------------------------
diff --git a/contrib/views/pig/src/main/resources/ui/pig-web/app/templates/pig/modal/confirmdelete.hbs b/contrib/views/pig/src/main/resources/ui/pig-web/app/templates/pig/modal/confirmdelete.hbs
new file mode 100644
index 0000000..39e3a1c
--- /dev/null
+++ b/contrib/views/pig/src/main/resources/ui/pig-web/app/templates/pig/modal/confirmdelete.hbs
@@ -0,0 +1,29 @@
+{{!
+   Licensed to the Apache Software Foundation (ASF) under one
+   or more contributor license agreements.  See the NOTICE file
+   distributed with this work for additional information
+   regarding copyright ownership.  The ASF licenses this file
+   to you under the Apache License, Version 2.0 (the
+   "License"); you may not use this file except in compliance
+   with the License.  You may obtain a copy of the License at
+  
+       http://www.apache.org/licenses/LICENSE-2.0
+  
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.
+}}
+
+<div class="modal-header">
+  <button type="button" class="close" data-dismiss="modal" aria-hidden="true">&times;</button>
+  <h4 class="modal-title">{{t 'scripts.modal.confirm_delete'}}</h4>
+</div>
+<div class="modal-body">
+{{t 'scripts.modal.confirm_delete_massage' titleBinding="content.title" tagName="p"}}
+</div>
+<div class="modal-footer">
+  <button type="button" {{action "close" target="view"}} class="btn btn-default" data-dismiss="modal">{{t 'common.cancel'}}</button>
+  <button type="button" {{action "confirm" content target="view"}} class="btn btn-danger">{{t 'common.delete'}}</button>
+</div>

http://git-wip-us.apache.org/repos/asf/ambari/blob/5eb22214/contrib/views/pig/src/main/resources/ui/pig-web/app/templates/pig/modal/createScript.hbs
----------------------------------------------------------------------
diff --git a/contrib/views/pig/src/main/resources/ui/pig-web/app/templates/pig/modal/createScript.hbs b/contrib/views/pig/src/main/resources/ui/pig-web/app/templates/pig/modal/createScript.hbs
new file mode 100644
index 0000000..6e536e9
--- /dev/null
+++ b/contrib/views/pig/src/main/resources/ui/pig-web/app/templates/pig/modal/createScript.hbs
@@ -0,0 +1,37 @@
+{{!
+   Licensed to the Apache Software Foundation (ASF) under one
+   or more contributor license agreements.  See the NOTICE file
+   distributed with this work for additional information
+   regarding copyright ownership.  The ASF licenses this file
+   to you under the Apache License, Version 2.0 (the
+   "License"); you may not use this file except in compliance
+   with the License.  You may obtain a copy of the License at
+  
+       http://www.apache.org/licenses/LICENSE-2.0
+  
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.
+}}
+
+<div class="modal-header">
+  <button type="button" class="close" data-dismiss="modal" aria-hidden="true">&times;</button>
+  <h4 class="modal-title">{{t 'scripts.modal.create_script'}}</h4>
+</div>
+<div class="modal-body">
+<div class="form-group">
+    <label for="exampleInputEmail1">{{t 'scripts.title'}}</label>
+    {{input class="form-control" placeholderTranslation="udfs.modal.udf_name" valueBinding="content.title"}}
+  </div>
+  <div class="form-group">
+    <label for="exampleInputPassword1">{{t 'common.path'}}</label>
+    {{input class="form-control" placeholderTranslation="scripts.modal.file_path_placeholder" valueBinding="filePath"}}
+    <small class="pull-right help-block">{{t 'scripts.modal.file_path_hint'}}</small>
+  </div>
+</div>
+<div class="modal-footer">
+  <button type="button" {{action "close" content target="view"}} class="btn btn-default" >{{t 'common.cancel'}}</button>
+  <button type="button" {{action "create" content target="view"}} {{bind-attr disabled="view.udfInvalid"}} class="btn btn-success">{{t 'common.create'}}</button>
+</div>

http://git-wip-us.apache.org/repos/asf/ambari/blob/5eb22214/contrib/views/pig/src/main/resources/ui/pig-web/app/templates/pig/modal/createUdf.hbs
----------------------------------------------------------------------
diff --git a/contrib/views/pig/src/main/resources/ui/pig-web/app/templates/pig/modal/createUdf.hbs b/contrib/views/pig/src/main/resources/ui/pig-web/app/templates/pig/modal/createUdf.hbs
new file mode 100644
index 0000000..a47ad1e
--- /dev/null
+++ b/contrib/views/pig/src/main/resources/ui/pig-web/app/templates/pig/modal/createUdf.hbs
@@ -0,0 +1,36 @@
+{{!
+   Licensed to the Apache Software Foundation (ASF) under one
+   or more contributor license agreements.  See the NOTICE file
+   distributed with this work for additional information
+   regarding copyright ownership.  The ASF licenses this file
+   to you under the Apache License, Version 2.0 (the
+   "License"); you may not use this file except in compliance
+   with the License.  You may obtain a copy of the License at
+  
+       http://www.apache.org/licenses/LICENSE-2.0
+  
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.
+}}
+
+<div class="modal-header">
+  <button type="button" class="close" data-dismiss="modal" aria-hidden="true">&times;</button>
+  <h4 class="modal-title">{{t 'udfs.modal.create_udf'}}</h4>
+</div>
+<div class="modal-body">
+<div class="form-group">
+    <label for="exampleInputEmail1">{{t 'common.name'}}</label>
+    {{input class="form-control" placeholderTranslation="udfs.modal.udf_name" valueBinding="content.name"}}
+  </div>
+  <div class="form-group">
+    <label for="exampleInputPassword1">{{t 'common.path'}}</label>
+    {{input class="form-control" placeholderTranslation="udfs.modal.hdfs_path" valueBinding="content.path"}}
+  </div>
+</div>
+<div class="modal-footer">
+  <button type="button" {{action "close" content target="view"}} class="btn btn-default" >{{t 'common.cancel'}}</button>
+  <button type="button" {{action "createUdf" content target="view"}} {{bind-attr disabled="view.udfInvalid"}} class="btn btn-success">{{t 'common.create'}}</button>
+</div>

http://git-wip-us.apache.org/repos/asf/ambari/blob/5eb22214/contrib/views/pig/src/main/resources/ui/pig-web/app/templates/pig/modal/modalLayout.hbs
----------------------------------------------------------------------
diff --git a/contrib/views/pig/src/main/resources/ui/pig-web/app/templates/pig/modal/modalLayout.hbs b/contrib/views/pig/src/main/resources/ui/pig-web/app/templates/pig/modal/modalLayout.hbs
new file mode 100644
index 0000000..79bebd9
--- /dev/null
+++ b/contrib/views/pig/src/main/resources/ui/pig-web/app/templates/pig/modal/modalLayout.hbs
@@ -0,0 +1,25 @@
+{{!
+   Licensed to the Apache Software Foundation (ASF) under one
+   or more contributor license agreements.  See the NOTICE file
+   distributed with this work for additional information
+   regarding copyright ownership.  The ASF licenses this file
+   to you under the Apache License, Version 2.0 (the
+   "License"); you may not use this file except in compliance
+   with the License.  You may obtain a copy of the License at
+  
+       http://www.apache.org/licenses/LICENSE-2.0
+  
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.
+}}
+
+<div class="modal fade in" data-backdrop="static">
+  <div class="modal-dialog">
+    <div class="modal-content">
+      {{yield}}
+    </div><!-- /.modal-content -->
+  </div><!-- /.modal-dialog -->
+</div><!-- /.modal -->

http://git-wip-us.apache.org/repos/asf/ambari/blob/5eb22214/contrib/views/pig/src/main/resources/ui/pig-web/app/templates/pig/scriptEdit.hbs
----------------------------------------------------------------------
diff --git a/contrib/views/pig/src/main/resources/ui/pig-web/app/templates/pig/scriptEdit.hbs b/contrib/views/pig/src/main/resources/ui/pig-web/app/templates/pig/scriptEdit.hbs
new file mode 100644
index 0000000..45d391a
--- /dev/null
+++ b/contrib/views/pig/src/main/resources/ui/pig-web/app/templates/pig/scriptEdit.hbs
@@ -0,0 +1,120 @@
+{{!
+   Licensed to the Apache Software Foundation (ASF) under one
+   or more contributor license agreements.  See the NOTICE file
+   distributed with this work for additional information
+   regarding copyright ownership.  The ASF licenses this file
+   to you under the Apache License, Version 2.0 (the
+   "License"); you may not use this file except in compliance
+   with the License.  You may obtain a copy of the License at
+  
+       http://www.apache.org/licenses/LICENSE-2.0
+  
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.
+}}
+
+<div class="edit-script">
+    <div {{bind-attr class=":panel :panel-editscript scriptError:panel-danger:panel-default"}} >
+      <div class="panel-heading">
+        <div class="head control-group">
+            {{outlet nav}}
+            <div class="btn-group">
+                {{input id="title" placeholderTranslation="scripts.title" class="form-control" disabled=controller.isJob valueBinding="content.title"}}
+            </div>
+            <div class="btn-group">
+                <input type="button" {{action "saveScript" content}} {{bind-attr class=":btn :btn-primary scriptDirty::disabled"}} {{translateAttr value="editor.save"}}
+                >
+            </div>
+            {{#if view.isEditConfirmed}}
+            {{view view.pigHelperView class="btn-group" }}
+            <div class="btn-group">
+                <button type="button" data-toggle="dropdown" {{bind-attr class=":btn :btn-default :dropdown-toggle ufdsList.length::disabled"}} >
+                  {{t 'editor.udfhelper'}}
+                  <span class="caret"></span>
+                </button>
+                <ul class="dropdown-menu">
+                {{#each ufdsList}}
+                  <li><a href="#" {{action 'insertUdf' this target="view" }}>{{this.name}}</a></li>
+                {{/each}}
+                </ul>
+            </div>
+            {{/if}}
+        </div>
+      </div>
+      <div class="panel-body" >
+        <span>
+            {{#with controller }}
+              {{#each controller.pigArgumentsPull}}
+                <span {{bind-attr class=":argument controller.isScript:editable:"}} >
+                  <span class="title"> {{this}} </span>
+                  {{#if controller.isScript}}
+                  <button {{action "removeArgument" this}}  class="close rm-arg">
+                      &times;
+                  </button>
+                  {{/if}}
+                </span>
+              {{/each}}
+            {{/with}}
+            {{#if controller.isScript}}
+            {{view view.argumentInput}}
+              <button {{action "sendArgument" target="view.argumentInput" }} type="button" class="btn btn-default btn-xs" >
+                <span class="glyphicon glyphicon-plus"></span> {{t 'common.add'}}
+              </button>
+            {{/if}}
+        </span>
+        <kbd class="file-path pull-right" data-toggle="tooltip" data-placement="bottom"{{translateAttr title="udfs.tooltips.path"}} >
+          {{#unless content.pigScript.isLoaded}}
+            <div class="spinner-sm"></div>
+          {{/unless}}
+          {{#if content.pigScript.isLoaded}}
+            {{content.pigScript.id}}
+          {{/if}}
+        </kbd>
+      </div>
+      <div class="editor-container">
+        {{#if controller.isJob}}
+          {{#unless view.isEditConfirmed}}
+            <div class="edit-confirm">
+              <div class="well edit-confirm-container">
+                When you executed job, script was copied to another place in filesystem. <br />
+                You're going to edit the <u>copy of original script</u> from history<br />
+                <button {{action "confirmEdit" target="view"}} class="btn btn-large" type="button">Edit script from history</button>
+                {{#if content.scriptId}}
+                  <button {{action "returnToOriginal" content}} class="btn btn-large btn-primary" type="button">Return to original file</button>
+                {{/if}}
+              </div>
+            </div>
+          {{/unless}}
+        {{/if}}
+        {{view view.codeMirrorView id="pig_script" contentBinding="content.pigScript"}}
+      </div>
+    </div>
+
+    {{outlet main}}
+
+    <div class="form-inline pigParams">
+    {{#each pigParams}}
+    <div class="form-group">
+      <label class="control-label">{{this.title}}</label>
+      <div class="">
+       {{view view.pigParamView class='form-control input-sm' valueBinding='value'}}
+      </div>
+    </div>
+    {{/each}}
+    </div>
+
+    <div class="controls">
+      {{#unless isExec}}
+        <button {{action "execute" content 'execute' }} type="button" class="btn btn-default">{{t 'editor.execute'}}</button>
+        <button {{action "execute" content 'explain' }} type="button" class="btn btn-default">{{t 'editor.explain'}}</button>
+        <button {{action "execute" content 'syntax_check' }} type="button" class="btn btn-default">{{t 'editor.syntax_check'}}</button>
+      {{/unless}}
+
+      {{#if isExec}}
+        <div class="spinner-sm"></div>
+      {{/if}}
+    </div>
+</div>

http://git-wip-us.apache.org/repos/asf/ambari/blob/5eb22214/contrib/views/pig/src/main/resources/ui/pig-web/app/templates/pig/scriptEditIndex.hbs
----------------------------------------------------------------------
diff --git a/contrib/views/pig/src/main/resources/ui/pig-web/app/templates/pig/scriptEditIndex.hbs b/contrib/views/pig/src/main/resources/ui/pig-web/app/templates/pig/scriptEditIndex.hbs
new file mode 100644
index 0000000..0efb5b2
--- /dev/null
+++ b/contrib/views/pig/src/main/resources/ui/pig-web/app/templates/pig/scriptEditIndex.hbs
@@ -0,0 +1,18 @@
+{{!
+   Licensed to the Apache Software Foundation (ASF) under one
+   or more contributor license agreements.  See the NOTICE file
+   distributed with this work for additional information
+   regarding copyright ownership.  The ASF licenses this file
+   to you under the Apache License, Version 2.0 (the
+   "License"); you may not use this file except in compliance
+   with the License.  You may obtain a copy of the License at
+  
+       http://www.apache.org/licenses/LICENSE-2.0
+  
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.
+}}
+

http://git-wip-us.apache.org/repos/asf/ambari/blob/5eb22214/contrib/views/pig/src/main/resources/ui/pig-web/app/templates/pig/scriptList.hbs
----------------------------------------------------------------------
diff --git a/contrib/views/pig/src/main/resources/ui/pig-web/app/templates/pig/scriptList.hbs b/contrib/views/pig/src/main/resources/ui/pig-web/app/templates/pig/scriptList.hbs
new file mode 100644
index 0000000..fdba0a6
--- /dev/null
+++ b/contrib/views/pig/src/main/resources/ui/pig-web/app/templates/pig/scriptList.hbs
@@ -0,0 +1,57 @@
+{{!
+   Licensed to the Apache Software Foundation (ASF) under one
+   or more contributor license agreements.  See the NOTICE file
+   distributed with this work for additional information
+   regarding copyright ownership.  The ASF licenses this file
+   to you under the Apache License, Version 2.0 (the
+   "License"); you may not use this file except in compliance
+   with the License.  You may obtain a copy of the License at
+  
+       http://www.apache.org/licenses/LICENSE-2.0
+  
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.
+}}
+
+<div class="panel panel-default panel-scriptlist">
+  <div class="panel-heading">
+    {{t 'scripts.scripts'}}
+    <a {{action "createScript"}} class="btn btn-default btn-sm pull-right new-script"><span class="glyphicon glyphicon-plus"></span> {{t 'scripts.newscript'}}</a>
+  </div>
+  
+  <table class="table table-bordered table-striped ">
+    <thead> 
+      <tr class="label-row"> 
+        <th class="first">{{t 'common.name'}}</th> 
+        <th>{{t 'common.created'}}</th> 
+        <th></th> 
+      </tr>
+    </thead>
+    <tbody> 
+    {{#each content}}
+      <tr> 
+
+        <td class="first">{{#link-to 'pig.scriptEdit' this.id}}
+          {{#if this.isNew}}
+            <div class="spinner-sm"></div>
+          {{/if}}
+          {{#unless this.isNew}}
+            {{this.title}}
+          {{/unless}}
+        {{/link-to}}</td>
+        <td><span class="date">{{showDate this.dateCreated 'YYYY-MM-DD HH:mm'}}</span></td>
+        <td> 
+          {{#unless this.isNew}}
+            <a>{{t 'common.history'}}</a> - <a>{{t 'common.clone'}}</a> - <a href="#" {{action "deletescript" this}}>{{t 'common.delete'}}</a>
+          {{/unless}}
+        </td>
+      </tr>
+    {{/each}}
+    </tbody>
+  </table>
+</div>
+
+{{outlet modal}}

http://git-wip-us.apache.org/repos/asf/ambari/blob/5eb22214/contrib/views/pig/src/main/resources/ui/pig-web/app/templates/pig/scriptResults.hbs
----------------------------------------------------------------------
diff --git a/contrib/views/pig/src/main/resources/ui/pig-web/app/templates/pig/scriptResults.hbs b/contrib/views/pig/src/main/resources/ui/pig-web/app/templates/pig/scriptResults.hbs
new file mode 100644
index 0000000..0efb5b2
--- /dev/null
+++ b/contrib/views/pig/src/main/resources/ui/pig-web/app/templates/pig/scriptResults.hbs
@@ -0,0 +1,18 @@
+{{!
+   Licensed to the Apache Software Foundation (ASF) under one
+   or more contributor license agreements.  See the NOTICE file
+   distributed with this work for additional information
+   regarding copyright ownership.  The ASF licenses this file
+   to you under the Apache License, Version 2.0 (the
+   "License"); you may not use this file except in compliance
+   with the License.  You may obtain a copy of the License at
+  
+       http://www.apache.org/licenses/LICENSE-2.0
+  
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.
+}}
+

http://git-wip-us.apache.org/repos/asf/ambari/blob/5eb22214/contrib/views/pig/src/main/resources/ui/pig-web/app/templates/pig/scriptResultsNav.hbs
----------------------------------------------------------------------
diff --git a/contrib/views/pig/src/main/resources/ui/pig-web/app/templates/pig/scriptResultsNav.hbs b/contrib/views/pig/src/main/resources/ui/pig-web/app/templates/pig/scriptResultsNav.hbs
new file mode 100644
index 0000000..a94716f
--- /dev/null
+++ b/contrib/views/pig/src/main/resources/ui/pig-web/app/templates/pig/scriptResultsNav.hbs
@@ -0,0 +1,19 @@
+{{!
+   Licensed to the Apache Software Foundation (ASF) under one
+   or more contributor license agreements.  See the NOTICE file
+   distributed with this work for additional information
+   regarding copyright ownership.  The ASF licenses this file
+   to you under the Apache License, Version 2.0 (the
+   "License"); you may not use this file except in compliance
+   with the License.  You may obtain a copy of the License at
+  
+       http://www.apache.org/licenses/LICENSE-2.0
+  
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.
+}}
+
+{{view view.navResultsView }}

http://git-wip-us.apache.org/repos/asf/ambari/blob/5eb22214/contrib/views/pig/src/main/resources/ui/pig-web/app/templates/pig/udfs.hbs
----------------------------------------------------------------------
diff --git a/contrib/views/pig/src/main/resources/ui/pig-web/app/templates/pig/udfs.hbs b/contrib/views/pig/src/main/resources/ui/pig-web/app/templates/pig/udfs.hbs
new file mode 100644
index 0000000..1ecd6be
--- /dev/null
+++ b/contrib/views/pig/src/main/resources/ui/pig-web/app/templates/pig/udfs.hbs
@@ -0,0 +1,45 @@
+{{!
+   Licensed to the Apache Software Foundation (ASF) under one
+   or more contributor license agreements.  See the NOTICE file
+   distributed with this work for additional information
+   regarding copyright ownership.  The ASF licenses this file
+   to you under the Apache License, Version 2.0 (the
+   "License"); you may not use this file except in compliance
+   with the License.  You may obtain a copy of the License at
+  
+       http://www.apache.org/licenses/LICENSE-2.0
+  
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.
+}}
+
+<div class="panel panel-default panel-udfs">
+  <div class="panel-heading">
+    UDFs
+    <a {{action "createUdfModal"}} class="btn btn-default btn-sm pull-right upload-udf"><span class="glyphicon glyphicon-plus"></span>{{t 'common.create'}}</a>
+  </div>
+  
+  <table class="table table-bordered table-striped">
+    <thead> 
+      <tr class="label-row">
+        <th class="first">{{t 'common.name'}}</th> 
+        <th>{{t 'common.path'}}</th> 
+        <th>{{t 'common.owner'}}</th> 
+        <th></th> 
+      </tr>
+    </thead>
+    <tbody>
+    {{#each content}}
+        <tr> 
+          <td> {{this.name}}</td>
+          <td> {{this.path}}</td>
+          <td> {{this.owner}}</td>
+          <td><a href="#" {{action "deleteUdf" this}} >{{t 'common.delete'}}</a></td>
+        </tr>
+    {{/each}}
+    </tbody>
+  </table>
+</div>


[4/7] AMBARI-5616 - Ambari Views: Pig view (Roman Rader via tbeerbower)

Posted by tb...@apache.org.
http://git-wip-us.apache.org/repos/asf/ambari/blob/5eb22214/contrib/views/pig/src/main/resources/ui/pig-web/app/assets/static/fonts/glyphicons-halflings-regular.svg
----------------------------------------------------------------------
diff --git a/contrib/views/pig/src/main/resources/ui/pig-web/app/assets/static/fonts/glyphicons-halflings-regular.svg b/contrib/views/pig/src/main/resources/ui/pig-web/app/assets/static/fonts/glyphicons-halflings-regular.svg
new file mode 100644
index 0000000..4469488
--- /dev/null
+++ b/contrib/views/pig/src/main/resources/ui/pig-web/app/assets/static/fonts/glyphicons-halflings-regular.svg
@@ -0,0 +1,229 @@
+<?xml version="1.0" standalone="no"?>
+<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd" >
+<svg xmlns="http://www.w3.org/2000/svg">
+<metadata></metadata>
+<defs>
+<font id="glyphicons_halflingsregular" horiz-adv-x="1200" >
+<font-face units-per-em="1200" ascent="960" descent="-240" />
+<missing-glyph horiz-adv-x="500" />
+<glyph />
+<glyph />
+<glyph unicode="&#xd;" />
+<glyph unicode=" " />
+<glyph unicode="*" d="M100 500v200h259l-183 183l141 141l183 -183v259h200v-259l183 183l141 -141l-183 -183h259v-200h-259l183 -183l-141 -141l-183 183v-259h-200v259l-183 -183l-141 141l183 183h-259z" />
+<glyph unicode="+" d="M0 400v300h400v400h300v-400h400v-300h-400v-400h-300v400h-400z" />
+<glyph unicode="&#xa0;" />
+<glyph unicode="&#x2000;" horiz-adv-x="652" />
+<glyph unicode="&#x2001;" horiz-adv-x="1304" />
+<glyph unicode="&#x2002;" horiz-adv-x="652" />
+<glyph unicode="&#x2003;" horiz-adv-x="1304" />
+<glyph unicode="&#x2004;" horiz-adv-x="434" />
+<glyph unicode="&#x2005;" horiz-adv-x="326" />
+<glyph unicode="&#x2006;" horiz-adv-x="217" />
+<glyph unicode="&#x2007;" horiz-adv-x="217" />
+<glyph unicode="&#x2008;" horiz-adv-x="163" />
+<glyph unicode="&#x2009;" horiz-adv-x="260" />
+<glyph unicode="&#x200a;" horiz-adv-x="72" />
+<glyph unicode="&#x202f;" horiz-adv-x="260" />
+<glyph unicode="&#x205f;" horiz-adv-x="326" />
+<glyph unicode="&#x20ac;" d="M100 500l100 100h113q0 47 5 100h-218l100 100h135q37 167 112 257q117 141 297 141q242 0 354 -189q60 -103 66 -209h-181q0 55 -25.5 99t-63.5 68t-75 36.5t-67 12.5q-24 0 -52.5 -10t-62.5 -32t-65.5 -67t-50.5 -107h379l-100 -100h-300q-6 -46 -6 -100h406l-100 -100 h-300q9 -74 33 -132t52.5 -91t62 -54.5t59 -29t46.5 -7.5q29 0 66 13t75 37t63.5 67.5t25.5 96.5h174q-31 -172 -128 -278q-107 -117 -274 -117q-205 0 -324 158q-36 46 -69 131.5t-45 205.5h-217z" />
+<glyph unicode="&#x2212;" d="M200 400h900v300h-900v-300z" />
+<glyph unicode="&#x2601;" d="M-14 494q0 -80 56.5 -137t135.5 -57h750q120 0 205 86t85 208q0 120 -85 206.5t-205 86.5q-46 0 -90 -14q-44 97 -134.5 156.5t-200.5 59.5q-152 0 -260 -107.5t-108 -260.5q0 -25 2 -37q-66 -14 -108.5 -67.5t-42.5 -122.5z" />
+<glyph unicode="&#x2709;" d="M0 100l400 400l200 -200l200 200l400 -400h-1200zM0 300v600l300 -300zM0 1100l600 -603l600 603h-1200zM900 600l300 300v-600z" />
+<glyph unicode="&#x270f;" d="M-13 -13l333 112l-223 223zM187 403l214 -214l614 614l-214 214zM887 1103l214 -214l99 92q13 13 13 32.5t-13 33.5l-153 153q-15 13 -33 13t-33 -13z" />
+<glyph unicode="&#xe000;" horiz-adv-x="500" d="M0 0z" />
+<glyph unicode="&#xe001;" d="M0 1200h1200l-500 -550v-550h300v-100h-800v100h300v550z" />
+<glyph unicode="&#xe002;" d="M14 84q18 -55 86 -75.5t147 5.5q65 21 109 69t44 90v606l600 155v-521q-64 16 -138 -7q-79 -26 -122.5 -83t-25.5 -111q17 -55 85.5 -75.5t147.5 4.5q70 23 111.5 63.5t41.5 95.5v881q0 10 -7 15.5t-17 2.5l-752 -193q-10 -3 -17 -12.5t-7 -19.5v-689q-64 17 -138 -7 q-79 -25 -122.5 -82t-25.5 -112z" />
+<glyph unicode="&#xe003;" d="M23 693q0 200 142 342t342 142t342 -142t142 -342q0 -142 -78 -261l300 -300q7 -8 7 -18t-7 -18l-109 -109q-8 -7 -18 -7t-18 7l-300 300q-119 -78 -261 -78q-200 0 -342 142t-142 342zM176 693q0 -136 97 -233t234 -97t233.5 96.5t96.5 233.5t-96.5 233.5t-233.5 96.5 t-234 -97t-97 -233z" />
+<glyph unicode="&#xe005;" d="M100 784q0 64 28 123t73 100.5t104.5 64t119 20.5t120 -38.5t104.5 -104.5q48 69 109.5 105t121.5 38t118.5 -20.5t102.5 -64t71 -100.5t27 -123q0 -57 -33.5 -117.5t-94 -124.5t-126.5 -127.5t-150 -152.5t-146 -174q-62 85 -145.5 174t-149.5 152.5t-126.5 127.5 t-94 124.5t-33.5 117.5z" />
+<glyph unicode="&#xe006;" d="M-72 800h479l146 400h2l146 -400h472l-382 -278l145 -449l-384 275l-382 -275l146 447zM168 71l2 1z" />
+<glyph unicode="&#xe007;" d="M-72 800h479l146 400h2l146 -400h472l-382 -278l145 -449l-384 275l-382 -275l146 447zM168 71l2 1zM237 700l196 -142l-73 -226l192 140l195 -141l-74 229l193 140h-235l-77 211l-78 -211h-239z" />
+<glyph unicode="&#xe008;" d="M0 0v143l400 257v100q-37 0 -68.5 74.5t-31.5 125.5v200q0 124 88 212t212 88t212 -88t88 -212v-200q0 -51 -31.5 -125.5t-68.5 -74.5v-100l400 -257v-143h-1200z" />
+<glyph unicode="&#xe009;" d="M0 0v1100h1200v-1100h-1200zM100 100h100v100h-100v-100zM100 300h100v100h-100v-100zM100 500h100v100h-100v-100zM100 700h100v100h-100v-100zM100 900h100v100h-100v-100zM300 100h600v400h-600v-400zM300 600h600v400h-600v-400zM1000 100h100v100h-100v-100z M1000 300h100v100h-100v-100zM1000 500h100v100h-100v-100zM1000 700h100v100h-100v-100zM1000 900h100v100h-100v-100z" />
+<glyph unicode="&#xe010;" d="M0 50v400q0 21 14.5 35.5t35.5 14.5h400q21 0 35.5 -14.5t14.5 -35.5v-400q0 -21 -14.5 -35.5t-35.5 -14.5h-400q-21 0 -35.5 14.5t-14.5 35.5zM0 650v400q0 21 14.5 35.5t35.5 14.5h400q21 0 35.5 -14.5t14.5 -35.5v-400q0 -21 -14.5 -35.5t-35.5 -14.5h-400 q-21 0 -35.5 14.5t-14.5 35.5zM600 50v400q0 21 14.5 35.5t35.5 14.5h400q21 0 35.5 -14.5t14.5 -35.5v-400q0 -21 -14.5 -35.5t-35.5 -14.5h-400q-21 0 -35.5 14.5t-14.5 35.5zM600 650v400q0 21 14.5 35.5t35.5 14.5h400q21 0 35.5 -14.5t14.5 -35.5v-400 q0 -21 -14.5 -35.5t-35.5 -14.5h-400q-21 0 -35.5 14.5t-14.5 35.5z" />
+<glyph unicode="&#xe011;" d="M0 50v200q0 21 14.5 35.5t35.5 14.5h200q21 0 35.5 -14.5t14.5 -35.5v-200q0 -21 -14.5 -35.5t-35.5 -14.5h-200q-21 0 -35.5 14.5t-14.5 35.5zM0 450v200q0 21 14.5 35.5t35.5 14.5h200q21 0 35.5 -14.5t14.5 -35.5v-200q0 -21 -14.5 -35.5t-35.5 -14.5h-200 q-21 0 -35.5 14.5t-14.5 35.5zM0 850v200q0 21 14.5 35.5t35.5 14.5h200q21 0 35.5 -14.5t14.5 -35.5v-200q0 -21 -14.5 -35.5t-35.5 -14.5h-200q-21 0 -35.5 14.5t-14.5 35.5zM400 50v200q0 21 14.5 35.5t35.5 14.5h200q21 0 35.5 -14.5t14.5 -35.5v-200q0 -21 -14.5 -35.5 t-35.5 -14.5h-200q-21 0 -35.5 14.5t-14.5 35.5zM400 450v200q0 21 14.5 35.5t35.5 14.5h200q21 0 35.5 -14.5t14.5 -35.5v-200q0 -21 -14.5 -35.5t-35.5 -14.5h-200q-21 0 -35.5 14.5t-14.5 35.5zM400 850v200q0 21 14.5 35.5t35.5 14.5h200q21 0 35.5 -14.5t14.5 -35.5 v-200q0 -21 -14.5 -35.5t-35.5 -14.5h-200q-21 0 -35.5 14.5t-14.5 35.5zM800 50v200q0 21 14.5 35.5t35.5 14.5h200q21 0 35.5 -14.5t14.5 -35.5v-200q0 -21 -14.5 -35.5t-35.5 -14.5h-200q-21 0 -35.5 14.5t-14.5 35.5zM800 450v200q0 
 21 14.5 35.5t35.5 14.5h200 q21 0 35.5 -14.5t14.5 -35.5v-200q0 -21 -14.5 -35.5t-35.5 -14.5h-200q-21 0 -35.5 14.5t-14.5 35.5zM800 850v200q0 21 14.5 35.5t35.5 14.5h200q21 0 35.5 -14.5t14.5 -35.5v-200q0 -21 -14.5 -35.5t-35.5 -14.5h-200q-21 0 -35.5 14.5t-14.5 35.5z" />
+<glyph unicode="&#xe012;" d="M0 50v200q0 21 14.5 35.5t35.5 14.5h200q21 0 35.5 -14.5t14.5 -35.5v-200q0 -21 -14.5 -35.5t-35.5 -14.5h-200q-21 0 -35.5 14.5t-14.5 35.5zM0 450q0 -21 14.5 -35.5t35.5 -14.5h200q21 0 35.5 14.5t14.5 35.5v200q0 21 -14.5 35.5t-35.5 14.5h-200q-21 0 -35.5 -14.5 t-14.5 -35.5v-200zM0 850v200q0 21 14.5 35.5t35.5 14.5h200q21 0 35.5 -14.5t14.5 -35.5v-200q0 -21 -14.5 -35.5t-35.5 -14.5h-200q-21 0 -35.5 14.5t-14.5 35.5zM400 50v200q0 21 14.5 35.5t35.5 14.5h700q21 0 35.5 -14.5t14.5 -35.5v-200q0 -21 -14.5 -35.5 t-35.5 -14.5h-700q-21 0 -35.5 14.5t-14.5 35.5zM400 450v200q0 21 14.5 35.5t35.5 14.5h700q21 0 35.5 -14.5t14.5 -35.5v-200q0 -21 -14.5 -35.5t-35.5 -14.5h-700q-21 0 -35.5 14.5t-14.5 35.5zM400 850v200q0 21 14.5 35.5t35.5 14.5h700q21 0 35.5 -14.5t14.5 -35.5 v-200q0 -21 -14.5 -35.5t-35.5 -14.5h-700q-21 0 -35.5 14.5t-14.5 35.5z" />
+<glyph unicode="&#xe013;" d="M29 454l419 -420l818 820l-212 212l-607 -607l-206 207z" />
+<glyph unicode="&#xe014;" d="M106 318l282 282l-282 282l212 212l282 -282l282 282l212 -212l-282 -282l282 -282l-212 -212l-282 282l-282 -282z" />
+<glyph unicode="&#xe015;" d="M23 693q0 200 142 342t342 142t342 -142t142 -342q0 -142 -78 -261l300 -300q7 -8 7 -18t-7 -18l-109 -109q-8 -7 -18 -7t-18 7l-300 300q-119 -78 -261 -78q-200 0 -342 142t-142 342zM176 693q0 -136 97 -233t234 -97t233.5 96.5t96.5 233.5t-96.5 233.5t-233.5 96.5 t-234 -97t-97 -233zM300 600v200h100v100h200v-100h100v-200h-100v-100h-200v100h-100z" />
+<glyph unicode="&#xe016;" d="M23 694q0 200 142 342t342 142t342 -142t142 -342q0 -141 -78 -262l300 -299q7 -7 7 -18t-7 -18l-109 -109q-8 -8 -18 -8t-18 8l-300 299q-120 -77 -261 -77q-200 0 -342 142t-142 342zM176 694q0 -136 97 -233t234 -97t233.5 97t96.5 233t-96.5 233t-233.5 97t-234 -97 t-97 -233zM300 601h400v200h-400v-200z" />
+<glyph unicode="&#xe017;" d="M23 600q0 183 105 331t272 210v-166q-103 -55 -165 -155t-62 -220q0 -177 125 -302t302 -125t302 125t125 302q0 120 -62 220t-165 155v166q167 -62 272 -210t105 -331q0 -118 -45.5 -224.5t-123 -184t-184 -123t-224.5 -45.5t-224.5 45.5t-184 123t-123 184t-45.5 224.5 zM500 750q0 -21 14.5 -35.5t35.5 -14.5h100q21 0 35.5 14.5t14.5 35.5v400q0 21 -14.5 35.5t-35.5 14.5h-100q-21 0 -35.5 -14.5t-14.5 -35.5v-400z" />
+<glyph unicode="&#xe018;" d="M100 1h200v300h-200v-300zM400 1v500h200v-500h-200zM700 1v800h200v-800h-200zM1000 1v1200h200v-1200h-200z" />
+<glyph unicode="&#xe019;" d="M26 601q0 -33 6 -74l151 -38l2 -6q14 -49 38 -93l3 -5l-80 -134q45 -59 105 -105l133 81l5 -3q45 -26 94 -39l5 -2l38 -151q40 -5 74 -5q27 0 74 5l38 151l6 2q46 13 93 39l5 3l134 -81q56 44 104 105l-80 134l3 5q24 44 39 93l1 6l152 38q5 40 5 74q0 28 -5 73l-152 38 l-1 6q-16 51 -39 93l-3 5l80 134q-44 58 -104 105l-134 -81l-5 3q-45 25 -93 39l-6 1l-38 152q-40 5 -74 5q-27 0 -74 -5l-38 -152l-5 -1q-50 -14 -94 -39l-5 -3l-133 81q-59 -47 -105 -105l80 -134l-3 -5q-25 -47 -38 -93l-2 -6l-151 -38q-6 -48 -6 -73zM385 601 q0 88 63 151t152 63t152 -63t63 -151q0 -89 -63 -152t-152 -63t-152 63t-63 152z" />
+<glyph unicode="&#xe020;" d="M100 1025v50q0 10 7.5 17.5t17.5 7.5h275v100q0 41 29.5 70.5t70.5 29.5h300q41 0 70.5 -29.5t29.5 -70.5v-100h275q10 0 17.5 -7.5t7.5 -17.5v-50q0 -11 -7 -18t-18 -7h-1050q-11 0 -18 7t-7 18zM200 100v800h900v-800q0 -41 -29.5 -71t-70.5 -30h-700q-41 0 -70.5 30 t-29.5 71zM300 100h100v700h-100v-700zM500 100h100v700h-100v-700zM500 1100h300v100h-300v-100zM700 100h100v700h-100v-700zM900 100h100v700h-100v-700z" />
+<glyph unicode="&#xe021;" d="M1 601l656 644l644 -644h-200v-600h-300v400h-300v-400h-300v600h-200z" />
+<glyph unicode="&#xe022;" d="M100 25v1150q0 11 7 18t18 7h475v-500h400v-675q0 -11 -7 -18t-18 -7h-850q-11 0 -18 7t-7 18zM700 800v300l300 -300h-300z" />
+<glyph unicode="&#xe023;" d="M4 600q0 162 80 299t217 217t299 80t299 -80t217 -217t80 -299t-80 -299t-217 -217t-299 -80t-299 80t-217 217t-80 299zM186 600q0 -171 121.5 -292.5t292.5 -121.5t292.5 121.5t121.5 292.5t-121.5 292.5t-292.5 121.5t-292.5 -121.5t-121.5 -292.5zM500 500v400h100 v-300h200v-100h-300z" />
+<glyph unicode="&#xe024;" d="M-100 0l431 1200h209l-21 -300h162l-20 300h208l431 -1200h-538l-41 400h-242l-40 -400h-539zM488 500h224l-27 300h-170z" />
+<glyph unicode="&#xe025;" d="M0 0v400h490l-290 300h200v500h300v-500h200l-290 -300h490v-400h-1100zM813 200h175v100h-175v-100z" />
+<glyph unicode="&#xe026;" d="M1 600q0 122 47.5 233t127.5 191t191 127.5t233 47.5t233 -47.5t191 -127.5t127.5 -191t47.5 -233t-47.5 -233t-127.5 -191t-191 -127.5t-233 -47.5t-233 47.5t-191 127.5t-127.5 191t-47.5 233zM188 600q0 -170 121 -291t291 -121t291 121t121 291t-121 291t-291 121 t-291 -121t-121 -291zM350 600h150v300h200v-300h150l-250 -300z" />
+<glyph unicode="&#xe027;" d="M4 600q0 162 80 299t217 217t299 80t299 -80t217 -217t80 -299t-80 -299t-217 -217t-299 -80t-299 80t-217 217t-80 299zM186 600q0 -171 121.5 -292.5t292.5 -121.5t292.5 121.5t121.5 292.5t-121.5 292.5t-292.5 121.5t-292.5 -121.5t-121.5 -292.5zM350 600l250 300 l250 -300h-150v-300h-200v300h-150z" />
+<glyph unicode="&#xe028;" d="M0 25v475l200 700h800q199 -700 200 -700v-475q0 -11 -7 -18t-18 -7h-1150q-11 0 -18 7t-7 18zM200 500h200l50 -200h300l50 200h200l-97 500h-606z" />
+<glyph unicode="&#xe029;" d="M4 600q0 162 80 299t217 217t299 80t299 -80t217 -217t80 -299t-80 -299t-217 -217t-299 -80t-299 80t-217 217t-80 299zM186 600q0 -172 121.5 -293t292.5 -121t292.5 121t121.5 293q0 171 -121.5 292.5t-292.5 121.5t-292.5 -121.5t-121.5 -292.5zM500 397v401 l297 -200z" />
+<glyph unicode="&#xe030;" d="M23 600q0 -118 45.5 -224.5t123 -184t184 -123t224.5 -45.5t224.5 45.5t184 123t123 184t45.5 224.5h-150q0 -177 -125 -302t-302 -125t-302 125t-125 302t125 302t302 125q136 0 246 -81l-146 -146h400v400l-145 -145q-157 122 -355 122q-118 0 -224.5 -45.5t-184 -123 t-123 -184t-45.5 -224.5z" />
+<glyph unicode="&#xe031;" d="M23 600q0 118 45.5 224.5t123 184t184 123t224.5 45.5q198 0 355 -122l145 145v-400h-400l147 147q-112 80 -247 80q-177 0 -302 -125t-125 -302h-150zM100 0v400h400l-147 -147q112 -80 247 -80q177 0 302 125t125 302h150q0 -118 -45.5 -224.5t-123 -184t-184 -123 t-224.5 -45.5q-198 0 -355 122z" />
+<glyph unicode="&#xe032;" d="M100 0h1100v1200h-1100v-1200zM200 100v900h900v-900h-900zM300 200v100h100v-100h-100zM300 400v100h100v-100h-100zM300 600v100h100v-100h-100zM300 800v100h100v-100h-100zM500 200h500v100h-500v-100zM500 400v100h500v-100h-500zM500 600v100h500v-100h-500z M500 800v100h500v-100h-500z" />
+<glyph unicode="&#xe033;" d="M0 100v600q0 41 29.5 70.5t70.5 29.5h100v200q0 82 59 141t141 59h300q82 0 141 -59t59 -141v-200h100q41 0 70.5 -29.5t29.5 -70.5v-600q0 -41 -29.5 -70.5t-70.5 -29.5h-900q-41 0 -70.5 29.5t-29.5 70.5zM400 800h300v150q0 21 -14.5 35.5t-35.5 14.5h-200 q-21 0 -35.5 -14.5t-14.5 -35.5v-150z" />
+<glyph unicode="&#xe034;" d="M100 0v1100h100v-1100h-100zM300 400q60 60 127.5 84t127.5 17.5t122 -23t119 -30t110 -11t103 42t91 120.5v500q-40 -81 -101.5 -115.5t-127.5 -29.5t-138 25t-139.5 40t-125.5 25t-103 -29.5t-65 -115.5v-500z" />
+<glyph unicode="&#xe035;" d="M0 275q0 -11 7 -18t18 -7h50q11 0 18 7t7 18v300q0 127 70.5 231.5t184.5 161.5t245 57t245 -57t184.5 -161.5t70.5 -231.5v-300q0 -11 7 -18t18 -7h50q11 0 18 7t7 18v300q0 116 -49.5 227t-131 192.5t-192.5 131t-227 49.5t-227 -49.5t-192.5 -131t-131 -192.5 t-49.5 -227v-300zM200 20v460q0 8 6 14t14 6h160q8 0 14 -6t6 -14v-460q0 -8 -6 -14t-14 -6h-160q-8 0 -14 6t-6 14zM800 20v460q0 8 6 14t14 6h160q8 0 14 -6t6 -14v-460q0 -8 -6 -14t-14 -6h-160q-8 0 -14 6t-6 14z" />
+<glyph unicode="&#xe036;" d="M0 400h300l300 -200v800l-300 -200h-300v-400zM688 459l141 141l-141 141l71 71l141 -141l141 141l71 -71l-141 -141l141 -141l-71 -71l-141 141l-141 -141z" />
+<glyph unicode="&#xe037;" d="M0 400h300l300 -200v800l-300 -200h-300v-400zM700 857l69 53q111 -135 111 -310q0 -169 -106 -302l-67 54q86 110 86 248q0 146 -93 257z" />
+<glyph unicode="&#xe038;" d="M0 401v400h300l300 200v-800l-300 200h-300zM702 858l69 53q111 -135 111 -310q0 -170 -106 -303l-67 55q86 110 86 248q0 145 -93 257zM889 951l7 -8q123 -151 123 -344q0 -189 -119 -339l-7 -8l81 -66l6 8q142 178 142 405q0 230 -144 408l-6 8z" />
+<glyph unicode="&#xe039;" d="M0 0h500v500h-200v100h-100v-100h-200v-500zM0 600h100v100h400v100h100v100h-100v300h-500v-600zM100 100v300h300v-300h-300zM100 800v300h300v-300h-300zM200 200v100h100v-100h-100zM200 900h100v100h-100v-100zM500 500v100h300v-300h200v-100h-100v-100h-200v100 h-100v100h100v200h-200zM600 0v100h100v-100h-100zM600 1000h100v-300h200v-300h300v200h-200v100h200v500h-600v-200zM800 800v300h300v-300h-300zM900 0v100h300v-100h-300zM900 900v100h100v-100h-100zM1100 200v100h100v-100h-100z" />
+<glyph unicode="&#xe040;" d="M0 200h100v1000h-100v-1000zM100 0v100h300v-100h-300zM200 200v1000h100v-1000h-100zM500 0v91h100v-91h-100zM500 200v1000h200v-1000h-200zM700 0v91h100v-91h-100zM800 200v1000h100v-1000h-100zM900 0v91h200v-91h-200zM1000 200v1000h200v-1000h-200z" />
+<glyph unicode="&#xe041;" d="M1 700v475q0 10 7.5 17.5t17.5 7.5h474l700 -700l-500 -500zM148 953q0 -42 29 -71q30 -30 71.5 -30t71.5 30q29 29 29 71t-29 71q-30 30 -71.5 30t-71.5 -30q-29 -29 -29 -71z" />
+<glyph unicode="&#xe042;" d="M2 700v475q0 11 7 18t18 7h474l700 -700l-500 -500zM148 953q0 -42 30 -71q29 -30 71 -30t71 30q30 29 30 71t-30 71q-29 30 -71 30t-71 -30q-30 -29 -30 -71zM701 1200h100l700 -700l-500 -500l-50 50l450 450z" />
+<glyph unicode="&#xe043;" d="M100 0v1025l175 175h925v-1000l-100 -100v1000h-750l-100 -100h750v-1000h-900z" />
+<glyph unicode="&#xe044;" d="M200 0l450 444l450 -443v1150q0 20 -14.5 35t-35.5 15h-800q-21 0 -35.5 -15t-14.5 -35v-1151z" />
+<glyph unicode="&#xe045;" d="M0 100v700h200l100 -200h600l100 200h200v-700h-200v200h-800v-200h-200zM253 829l40 -124h592l62 124l-94 346q-2 11 -10 18t-18 7h-450q-10 0 -18 -7t-10 -18zM281 24l38 152q2 10 11.5 17t19.5 7h500q10 0 19.5 -7t11.5 -17l38 -152q2 -10 -3.5 -17t-15.5 -7h-600 q-10 0 -15.5 7t-3.5 17z" />
+<glyph unicode="&#xe046;" d="M0 200q0 -41 29.5 -70.5t70.5 -29.5h1000q41 0 70.5 29.5t29.5 70.5v600q0 41 -29.5 70.5t-70.5 29.5h-150q-4 8 -11.5 21.5t-33 48t-53 61t-69 48t-83.5 21.5h-200q-41 0 -82 -20.5t-70 -50t-52 -59t-34 -50.5l-12 -20h-150q-41 0 -70.5 -29.5t-29.5 -70.5v-600z M356 500q0 100 72 172t172 72t172 -72t72 -172t-72 -172t-172 -72t-172 72t-72 172zM494 500q0 -44 31 -75t75 -31t75 31t31 75t-31 75t-75 31t-75 -31t-31 -75zM900 700v100h100v-100h-100z" />
+<glyph unicode="&#xe047;" d="M53 0h365v66q-41 0 -72 11t-49 38t1 71l92 234h391l82 -222q16 -45 -5.5 -88.5t-74.5 -43.5v-66h417v66q-34 1 -74 43q-18 19 -33 42t-21 37l-6 13l-385 998h-93l-399 -1006q-24 -48 -52 -75q-12 -12 -33 -25t-36 -20l-15 -7v-66zM416 521l178 457l46 -140l116 -317h-340 z" />
+<glyph unicode="&#xe048;" d="M100 0v89q41 7 70.5 32.5t29.5 65.5v827q0 28 -1 39.5t-5.5 26t-15.5 21t-29 14t-49 14.5v70h471q120 0 213 -88t93 -228q0 -55 -11.5 -101.5t-28 -74t-33.5 -47.5t-28 -28l-12 -7q8 -3 21.5 -9t48 -31.5t60.5 -58t47.5 -91.5t21.5 -129q0 -84 -59 -156.5t-142 -111 t-162 -38.5h-500zM400 200h161q89 0 153 48.5t64 132.5q0 90 -62.5 154.5t-156.5 64.5h-159v-400zM400 700h139q76 0 130 61.5t54 138.5q0 82 -84 130.5t-239 48.5v-379z" />
+<glyph unicode="&#xe049;" d="M200 0v57q77 7 134.5 40.5t65.5 80.5l173 849q10 56 -10 74t-91 37q-6 1 -10.5 2.5t-9.5 2.5v57h425l2 -57q-33 -8 -62 -25.5t-46 -37t-29.5 -38t-17.5 -30.5l-5 -12l-128 -825q-10 -52 14 -82t95 -36v-57h-500z" />
+<glyph unicode="&#xe050;" d="M-75 200h75v800h-75l125 167l125 -167h-75v-800h75l-125 -167zM300 900v300h150h700h150v-300h-50q0 29 -8 48.5t-18.5 30t-33.5 15t-39.5 5.5t-50.5 1h-200v-850l100 -50v-100h-400v100l100 50v850h-200q-34 0 -50.5 -1t-40 -5.5t-33.5 -15t-18.5 -30t-8.5 -48.5h-49z " />
+<glyph unicode="&#xe051;" d="M33 51l167 125v-75h800v75l167 -125l-167 -125v75h-800v-75zM100 901v300h150h700h150v-300h-50q0 29 -8 48.5t-18 30t-33.5 15t-40 5.5t-50.5 1h-200v-650l100 -50v-100h-400v100l100 50v650h-200q-34 0 -50.5 -1t-39.5 -5.5t-33.5 -15t-18.5 -30t-8 -48.5h-50z" />
+<glyph unicode="&#xe052;" d="M0 50q0 -20 14.5 -35t35.5 -15h1100q21 0 35.5 15t14.5 35v100q0 21 -14.5 35.5t-35.5 14.5h-1100q-21 0 -35.5 -14.5t-14.5 -35.5v-100zM0 350q0 -20 14.5 -35t35.5 -15h800q21 0 35.5 15t14.5 35v100q0 21 -14.5 35.5t-35.5 14.5h-800q-21 0 -35.5 -14.5t-14.5 -35.5 v-100zM0 650q0 -20 14.5 -35t35.5 -15h1000q21 0 35.5 15t14.5 35v100q0 21 -14.5 35.5t-35.5 14.5h-1000q-21 0 -35.5 -14.5t-14.5 -35.5v-100zM0 950q0 -20 14.5 -35t35.5 -15h600q21 0 35.5 15t14.5 35v100q0 21 -14.5 35.5t-35.5 14.5h-600q-21 0 -35.5 -14.5 t-14.5 -35.5v-100z" />
+<glyph unicode="&#xe053;" d="M0 50q0 -20 14.5 -35t35.5 -15h1100q21 0 35.5 15t14.5 35v100q0 21 -14.5 35.5t-35.5 14.5h-1100q-21 0 -35.5 -14.5t-14.5 -35.5v-100zM0 650q0 -20 14.5 -35t35.5 -15h1100q21 0 35.5 15t14.5 35v100q0 21 -14.5 35.5t-35.5 14.5h-1100q-21 0 -35.5 -14.5t-14.5 -35.5 v-100zM200 350q0 -20 14.5 -35t35.5 -15h700q21 0 35.5 15t14.5 35v100q0 21 -14.5 35.5t-35.5 14.5h-700q-21 0 -35.5 -14.5t-14.5 -35.5v-100zM200 950q0 -20 14.5 -35t35.5 -15h700q21 0 35.5 15t14.5 35v100q0 21 -14.5 35.5t-35.5 14.5h-700q-21 0 -35.5 -14.5 t-14.5 -35.5v-100z" />
+<glyph unicode="&#xe054;" d="M0 50v100q0 21 14.5 35.5t35.5 14.5h1100q21 0 35.5 -14.5t14.5 -35.5v-100q0 -20 -14.5 -35t-35.5 -15h-1100q-21 0 -35.5 15t-14.5 35zM100 650v100q0 21 14.5 35.5t35.5 14.5h1000q21 0 35.5 -14.5t14.5 -35.5v-100q0 -20 -14.5 -35t-35.5 -15h-1000q-21 0 -35.5 15 t-14.5 35zM300 350v100q0 21 14.5 35.5t35.5 14.5h800q21 0 35.5 -14.5t14.5 -35.5v-100q0 -20 -14.5 -35t-35.5 -15h-800q-21 0 -35.5 15t-14.5 35zM500 950v100q0 21 14.5 35.5t35.5 14.5h600q21 0 35.5 -14.5t14.5 -35.5v-100q0 -20 -14.5 -35t-35.5 -15h-600 q-21 0 -35.5 15t-14.5 35z" />
+<glyph unicode="&#xe055;" d="M0 50v100q0 21 14.5 35.5t35.5 14.5h1100q21 0 35.5 -14.5t14.5 -35.5v-100q0 -20 -14.5 -35t-35.5 -15h-1100q-21 0 -35.5 15t-14.5 35zM0 350v100q0 21 14.5 35.5t35.5 14.5h1100q21 0 35.5 -14.5t14.5 -35.5v-100q0 -20 -14.5 -35t-35.5 -15h-1100q-21 0 -35.5 15 t-14.5 35zM0 650v100q0 21 14.5 35.5t35.5 14.5h1100q21 0 35.5 -14.5t14.5 -35.5v-100q0 -20 -14.5 -35t-35.5 -15h-1100q-21 0 -35.5 15t-14.5 35zM0 950v100q0 21 14.5 35.5t35.5 14.5h1100q21 0 35.5 -14.5t14.5 -35.5v-100q0 -20 -14.5 -35t-35.5 -15h-1100 q-21 0 -35.5 15t-14.5 35z" />
+<glyph unicode="&#xe056;" d="M0 50v100q0 21 14.5 35.5t35.5 14.5h100q21 0 35.5 -14.5t14.5 -35.5v-100q0 -20 -14.5 -35t-35.5 -15h-100q-21 0 -35.5 15t-14.5 35zM0 350v100q0 21 14.5 35.5t35.5 14.5h100q21 0 35.5 -14.5t14.5 -35.5v-100q0 -20 -14.5 -35t-35.5 -15h-100q-21 0 -35.5 15 t-14.5 35zM0 650v100q0 21 14.5 35.5t35.5 14.5h100q21 0 35.5 -14.5t14.5 -35.5v-100q0 -20 -14.5 -35t-35.5 -15h-100q-21 0 -35.5 15t-14.5 35zM0 950v100q0 21 14.5 35.5t35.5 14.5h100q21 0 35.5 -14.5t14.5 -35.5v-100q0 -20 -14.5 -35t-35.5 -15h-100q-21 0 -35.5 15 t-14.5 35zM300 50v100q0 21 14.5 35.5t35.5 14.5h800q21 0 35.5 -14.5t14.5 -35.5v-100q0 -20 -14.5 -35t-35.5 -15h-800q-21 0 -35.5 15t-14.5 35zM300 350v100q0 21 14.5 35.5t35.5 14.5h800q21 0 35.5 -14.5t14.5 -35.5v-100q0 -20 -14.5 -35t-35.5 -15h-800 q-21 0 -35.5 15t-14.5 35zM300 650v100q0 21 14.5 35.5t35.5 14.5h800q21 0 35.5 -14.5t14.5 -35.5v-100q0 -20 -14.5 -35t-35.5 -15h-800q-21 0 -35.5 15t-14.5 35zM300 950v100q0 21 14.5 35.5t35.5 14.5h800q21 0 35.5 -14.5t14.5 -35.5v-10
 0q0 -20 -14.5 -35t-35.5 -15 h-800q-21 0 -35.5 15t-14.5 35z" />
+<glyph unicode="&#xe057;" d="M-101 500v100h201v75l166 -125l-166 -125v75h-201zM300 0h100v1100h-100v-1100zM500 50q0 -20 14.5 -35t35.5 -15h600q20 0 35 15t15 35v100q0 21 -15 35.5t-35 14.5h-600q-21 0 -35.5 -14.5t-14.5 -35.5v-100zM500 350q0 -20 14.5 -35t35.5 -15h300q20 0 35 15t15 35 v100q0 21 -15 35.5t-35 14.5h-300q-21 0 -35.5 -14.5t-14.5 -35.5v-100zM500 650q0 -20 14.5 -35t35.5 -15h500q20 0 35 15t15 35v100q0 21 -15 35.5t-35 14.5h-500q-21 0 -35.5 -14.5t-14.5 -35.5v-100zM500 950q0 -20 14.5 -35t35.5 -15h100q20 0 35 15t15 35v100 q0 21 -15 35.5t-35 14.5h-100q-21 0 -35.5 -14.5t-14.5 -35.5v-100z" />
+<glyph unicode="&#xe058;" d="M1 50q0 -20 14.5 -35t35.5 -15h600q20 0 35 15t15 35v100q0 21 -15 35.5t-35 14.5h-600q-21 0 -35.5 -14.5t-14.5 -35.5v-100zM1 350q0 -20 14.5 -35t35.5 -15h300q20 0 35 15t15 35v100q0 21 -15 35.5t-35 14.5h-300q-21 0 -35.5 -14.5t-14.5 -35.5v-100zM1 650 q0 -20 14.5 -35t35.5 -15h500q20 0 35 15t15 35v100q0 21 -15 35.5t-35 14.5h-500q-21 0 -35.5 -14.5t-14.5 -35.5v-100zM1 950q0 -20 14.5 -35t35.5 -15h100q20 0 35 15t15 35v100q0 21 -15 35.5t-35 14.5h-100q-21 0 -35.5 -14.5t-14.5 -35.5v-100zM801 0v1100h100v-1100 h-100zM934 550l167 -125v75h200v100h-200v75z" />
+<glyph unicode="&#xe059;" d="M0 275v650q0 31 22 53t53 22h750q31 0 53 -22t22 -53v-650q0 -31 -22 -53t-53 -22h-750q-31 0 -53 22t-22 53zM900 600l300 300v-600z" />
+<glyph unicode="&#xe060;" d="M0 44v1012q0 18 13 31t31 13h1112q19 0 31.5 -13t12.5 -31v-1012q0 -18 -12.5 -31t-31.5 -13h-1112q-18 0 -31 13t-13 31zM100 263l247 182l298 -131l-74 156l293 318l236 -288v500h-1000v-737zM208 750q0 56 39 95t95 39t95 -39t39 -95t-39 -95t-95 -39t-95 39t-39 95z " />
+<glyph unicode="&#xe062;" d="M148 745q0 124 60.5 231.5t165 172t226.5 64.5q123 0 227 -63t164.5 -169.5t60.5 -229.5t-73 -272q-73 -114 -166.5 -237t-150.5 -189l-57 -66q-10 9 -27 26t-66.5 70.5t-96 109t-104 135.5t-100.5 155q-63 139 -63 262zM342 772q0 -107 75.5 -182.5t181.5 -75.5 q107 0 182.5 75.5t75.5 182.5t-75.5 182t-182.5 75t-182 -75.5t-75 -181.5z" />
+<glyph unicode="&#xe063;" d="M1 600q0 122 47.5 233t127.5 191t191 127.5t233 47.5t233 -47.5t191 -127.5t127.5 -191t47.5 -233t-47.5 -233t-127.5 -191t-191 -127.5t-233 -47.5t-233 47.5t-191 127.5t-127.5 191t-47.5 233zM173 600q0 -177 125.5 -302t301.5 -125v854q-176 0 -301.5 -125 t-125.5 -302z" />
+<glyph unicode="&#xe064;" d="M117 406q0 94 34 186t88.5 172.5t112 159t115 177t87.5 194.5q21 -71 57.5 -142.5t76 -130.5t83 -118.5t82 -117t70 -116t50 -125.5t18.5 -136q0 -89 -39 -165.5t-102 -126.5t-140 -79.5t-156 -33.5q-114 6 -211.5 53t-161.5 138.5t-64 210.5zM243 414q14 -82 59.5 -136 t136.5 -80l16 98q-7 6 -18 17t-34 48t-33 77q-15 73 -14 143.5t10 122.5l9 51q-92 -110 -119.5 -185t-12.5 -156z" />
+<glyph unicode="&#xe065;" d="M0 400v300q0 165 117.5 282.5t282.5 117.5q366 -6 397 -14l-186 -186h-311q-41 0 -70.5 -29.5t-29.5 -70.5v-500q0 -41 29.5 -70.5t70.5 -29.5h500q41 0 70.5 29.5t29.5 70.5v125l200 200v-225q0 -165 -117.5 -282.5t-282.5 -117.5h-300q-165 0 -282.5 117.5 t-117.5 282.5zM436 341l161 50l412 412l-114 113l-405 -405zM995 1015l113 -113l113 113l-21 85l-92 28z" />
+<glyph unicode="&#xe066;" d="M0 400v300q0 165 117.5 282.5t282.5 117.5h261l2 -80q-133 -32 -218 -120h-145q-41 0 -70.5 -29.5t-29.5 -70.5v-500q0 -41 29.5 -70.5t70.5 -29.5h500q41 0 70.5 29.5t29.5 70.5l200 153v-53q0 -165 -117.5 -282.5t-282.5 -117.5h-300q-165 0 -282.5 117.5t-117.5 282.5 zM423 524q30 38 81.5 64t103 35.5t99 14t77.5 3.5l29 -1v-209l360 324l-359 318v-216q-7 0 -19 -1t-48 -8t-69.5 -18.5t-76.5 -37t-76.5 -59t-62 -88t-39.5 -121.5z" />
+<glyph unicode="&#xe067;" d="M0 400v300q0 165 117.5 282.5t282.5 117.5h300q60 0 127 -23l-178 -177h-349q-41 0 -70.5 -29.5t-29.5 -70.5v-500q0 -41 29.5 -70.5t70.5 -29.5h500q41 0 70.5 29.5t29.5 70.5v69l200 200v-169q0 -165 -117.5 -282.5t-282.5 -117.5h-300q-165 0 -282.5 117.5 t-117.5 282.5zM342 632l283 -284l566 567l-136 137l-430 -431l-147 147z" />
+<glyph unicode="&#xe068;" d="M0 603l300 296v-198h200v200h-200l300 300l295 -300h-195v-200h200v198l300 -296l-300 -300v198h-200v-200h195l-295 -300l-300 300h200v200h-200v-198z" />
+<glyph unicode="&#xe069;" d="M200 50v1000q0 21 14.5 35.5t35.5 14.5h100q21 0 35.5 -14.5t14.5 -35.5v-437l500 487v-1100l-500 488v-438q0 -21 -14.5 -35.5t-35.5 -14.5h-100q-21 0 -35.5 14.5t-14.5 35.5z" />
+<glyph unicode="&#xe070;" d="M0 50v1000q0 21 14.5 35.5t35.5 14.5h100q21 0 35.5 -14.5t14.5 -35.5v-437l500 487v-487l500 487v-1100l-500 488v-488l-500 488v-438q0 -21 -14.5 -35.5t-35.5 -14.5h-100q-21 0 -35.5 14.5t-14.5 35.5z" />
+<glyph unicode="&#xe071;" d="M136 550l564 550v-487l500 487v-1100l-500 488v-488z" />
+<glyph unicode="&#xe072;" d="M200 0l900 550l-900 550v-1100z" />
+<glyph unicode="&#xe073;" d="M200 150q0 -21 14.5 -35.5t35.5 -14.5h200q21 0 35.5 14.5t14.5 35.5v800q0 21 -14.5 35.5t-35.5 14.5h-200q-21 0 -35.5 -14.5t-14.5 -35.5v-800zM600 150q0 -21 14.5 -35.5t35.5 -14.5h200q21 0 35.5 14.5t14.5 35.5v800q0 21 -14.5 35.5t-35.5 14.5h-200 q-21 0 -35.5 -14.5t-14.5 -35.5v-800z" />
+<glyph unicode="&#xe074;" d="M200 150q0 -20 14.5 -35t35.5 -15h800q21 0 35.5 15t14.5 35v800q0 21 -14.5 35.5t-35.5 14.5h-800q-21 0 -35.5 -14.5t-14.5 -35.5v-800z" />
+<glyph unicode="&#xe075;" d="M0 0v1100l500 -487v487l564 -550l-564 -550v488z" />
+<glyph unicode="&#xe076;" d="M0 0v1100l500 -487v487l500 -487v437q0 21 14.5 35.5t35.5 14.5h100q21 0 35.5 -14.5t14.5 -35.5v-1000q0 -21 -14.5 -35.5t-35.5 -14.5h-100q-21 0 -35.5 14.5t-14.5 35.5v438l-500 -488v488z" />
+<glyph unicode="&#xe077;" d="M300 0v1100l500 -487v437q0 21 14.5 35.5t35.5 14.5h100q21 0 35.5 -14.5t14.5 -35.5v-1000q0 -21 -14.5 -35.5t-35.5 -14.5h-100q-21 0 -35.5 14.5t-14.5 35.5v438z" />
+<glyph unicode="&#xe078;" d="M100 250v100q0 21 14.5 35.5t35.5 14.5h1000q21 0 35.5 -14.5t14.5 -35.5v-100q0 -21 -14.5 -35.5t-35.5 -14.5h-1000q-21 0 -35.5 14.5t-14.5 35.5zM100 500h1100l-550 564z" />
+<glyph unicode="&#xe079;" d="M185 599l592 -592l240 240l-353 353l353 353l-240 240z" />
+<glyph unicode="&#xe080;" d="M272 194l353 353l-353 353l241 240l572 -571l21 -22l-1 -1v-1l-592 -591z" />
+<glyph unicode="&#xe081;" d="M3 600q0 162 80 299.5t217.5 217.5t299.5 80t299.5 -80t217.5 -217.5t80 -299.5t-80 -300t-217.5 -218t-299.5 -80t-299.5 80t-217.5 218t-80 300zM300 500h200v-200h200v200h200v200h-200v200h-200v-200h-200v-200z" />
+<glyph unicode="&#xe082;" d="M3 600q0 162 80 299.5t217.5 217.5t299.5 80t299.5 -80t217.5 -217.5t80 -299.5t-80 -300t-217.5 -218t-299.5 -80t-299.5 80t-217.5 218t-80 300zM300 500h600v200h-600v-200z" />
+<glyph unicode="&#xe083;" d="M3 600q0 162 80 299.5t217.5 217.5t299.5 80t299.5 -80t217.5 -217.5t80 -299.5t-80 -300t-217.5 -218t-299.5 -80t-299.5 80t-217.5 218t-80 300zM246 459l213 -213l141 142l141 -142l213 213l-142 141l142 141l-213 212l-141 -141l-141 142l-212 -213l141 -141z" />
+<glyph unicode="&#xe084;" d="M3 600q0 162 80 299.5t217.5 217.5t299.5 80t299.5 -80t217.5 -217.5t80 -299.5t-80 -299.5t-217.5 -217.5t-299.5 -80t-299.5 80t-217.5 217.5t-80 299.5zM270 551l276 -277l411 411l-175 174l-236 -236l-102 102z" />
+<glyph unicode="&#xe085;" d="M3 600q0 162 80 299.5t217.5 217.5t299.5 80t299.5 -80t217.5 -217.5t80 -299.5t-80 -300t-217.5 -218t-299.5 -80t-299.5 80t-217.5 218t-80 300zM363 700h144q4 0 11.5 -1t11 -1t6.5 3t3 9t1 11t3.5 8.5t3.5 6t5.5 4t6.5 2.5t9 1.5t9 0.5h11.5h12.5q19 0 30 -10t11 -26 q0 -22 -4 -28t-27 -22q-5 -1 -12.5 -3t-27 -13.5t-34 -27t-26.5 -46t-11 -68.5h200q5 3 14 8t31.5 25.5t39.5 45.5t31 69t14 94q0 51 -17.5 89t-42 58t-58.5 32t-58.5 15t-51.5 3q-105 0 -172 -56t-67 -183zM500 300h200v100h-200v-100z" />
+<glyph unicode="&#xe086;" d="M3 600q0 162 80 299.5t217.5 217.5t299.5 80t299.5 -80t217.5 -217.5t80 -299.5t-80 -300t-217.5 -218t-299.5 -80t-299.5 80t-217.5 218t-80 300zM400 300h400v100h-100v300h-300v-100h100v-200h-100v-100zM500 800h200v100h-200v-100z" />
+<glyph unicode="&#xe087;" d="M0 500v200h194q15 60 36 104.5t55.5 86t88 69t126.5 40.5v200h200v-200q54 -20 113 -60t112.5 -105.5t71.5 -134.5h203v-200h-203q-25 -102 -116.5 -186t-180.5 -117v-197h-200v197q-140 27 -208 102.5t-98 200.5h-194zM290 500q24 -73 79.5 -127.5t130.5 -78.5v206h200 v-206q149 48 201 206h-201v200h200q-25 74 -76 127.5t-124 76.5v-204h-200v203q-75 -24 -130 -77.5t-79 -125.5h209v-200h-210z" />
+<glyph unicode="&#xe088;" d="M4 600q0 162 80 299t217 217t299 80t299 -80t217 -217t80 -299t-80 -299t-217 -217t-299 -80t-299 80t-217 217t-80 299zM186 600q0 -171 121.5 -292.5t292.5 -121.5t292.5 121.5t121.5 292.5t-121.5 292.5t-292.5 121.5t-292.5 -121.5t-121.5 -292.5zM356 465l135 135 l-135 135l109 109l135 -135l135 135l109 -109l-135 -135l135 -135l-109 -109l-135 135l-135 -135z" />
+<glyph unicode="&#xe089;" d="M4 600q0 162 80 299t217 217t299 80t299 -80t217 -217t80 -299t-80 -299t-217 -217t-299 -80t-299 80t-217 217t-80 299zM186 600q0 -171 121.5 -292.5t292.5 -121.5t292.5 121.5t121.5 292.5t-121.5 292.5t-292.5 121.5t-292.5 -121.5t-121.5 -292.5zM322 537l141 141 l87 -87l204 205l142 -142l-346 -345z" />
+<glyph unicode="&#xe090;" d="M4 600q0 162 80 299t217 217t299 80t299 -80t217 -217t80 -299t-80 -299t-217 -217t-299 -80t-299 80t-217 217t-80 299zM186 600q0 -115 62 -215l568 567q-100 62 -216 62q-171 0 -292.5 -121.5t-121.5 -292.5zM391 245q97 -59 209 -59q171 0 292.5 121.5t121.5 292.5 q0 112 -59 209z" />
+<glyph unicode="&#xe091;" d="M0 547l600 453v-300h600v-300h-600v-301z" />
+<glyph unicode="&#xe092;" d="M0 400v300h600v300l600 -453l-600 -448v301h-600z" />
+<glyph unicode="&#xe093;" d="M204 600l450 600l444 -600h-298v-600h-300v600h-296z" />
+<glyph unicode="&#xe094;" d="M104 600h296v600h300v-600h298l-449 -600z" />
+<glyph unicode="&#xe095;" d="M0 200q6 132 41 238.5t103.5 193t184 138t271.5 59.5v271l600 -453l-600 -448v301q-95 -2 -183 -20t-170 -52t-147 -92.5t-100 -135.5z" />
+<glyph unicode="&#xe096;" d="M0 0v400l129 -129l294 294l142 -142l-294 -294l129 -129h-400zM635 777l142 -142l294 294l129 -129v400h-400l129 -129z" />
+<glyph unicode="&#xe097;" d="M34 176l295 295l-129 129h400v-400l-129 130l-295 -295zM600 600v400l129 -129l295 295l142 -141l-295 -295l129 -130h-400z" />
+<glyph unicode="&#xe101;" d="M23 600q0 118 45.5 224.5t123 184t184 123t224.5 45.5t224.5 -45.5t184 -123t123 -184t45.5 -224.5t-45.5 -224.5t-123 -184t-184 -123t-224.5 -45.5t-224.5 45.5t-184 123t-123 184t-45.5 224.5zM456 851l58 -302q4 -20 21.5 -34.5t37.5 -14.5h54q20 0 37.5 14.5 t21.5 34.5l58 302q4 20 -8 34.5t-33 14.5h-207q-20 0 -32 -14.5t-8 -34.5zM500 300h200v100h-200v-100z" />
+<glyph unicode="&#xe102;" d="M0 800h100v-200h400v300h200v-300h400v200h100v100h-111v6t-1 15t-3 18l-34 172q-11 39 -41.5 63t-69.5 24q-32 0 -61 -17l-239 -144q-22 -13 -40 -35q-19 24 -40 36l-238 144q-33 18 -62 18q-39 0 -69.5 -23t-40.5 -61l-35 -177q-2 -8 -3 -18t-1 -15v-6h-111v-100z M100 0h400v400h-400v-400zM200 900q-3 0 14 48t35 96l18 47l214 -191h-281zM700 0v400h400v-400h-400zM731 900l202 197q5 -12 12 -32.5t23 -64t25 -72t7 -28.5h-269z" />
+<glyph unicode="&#xe103;" d="M0 -22v143l216 193q-9 53 -13 83t-5.5 94t9 113t38.5 114t74 124q47 60 99.5 102.5t103 68t127.5 48t145.5 37.5t184.5 43.5t220 58.5q0 -189 -22 -343t-59 -258t-89 -181.5t-108.5 -120t-122 -68t-125.5 -30t-121.5 -1.5t-107.5 12.5t-87.5 17t-56.5 7.5l-99 -55z M238.5 300.5q19.5 -6.5 86.5 76.5q55 66 367 234q70 38 118.5 69.5t102 79t99 111.5t86.5 148q22 50 24 60t-6 19q-7 5 -17 5t-26.5 -14.5t-33.5 -39.5q-35 -51 -113.5 -108.5t-139.5 -89.5l-61 -32q-369 -197 -458 -401q-48 -111 -28.5 -117.5z" />
+<glyph unicode="&#xe104;" d="M111 408q0 -33 5 -63q9 -56 44 -119.5t105 -108.5q31 -21 64 -16t62 23.5t57 49.5t48 61.5t35 60.5q32 66 39 184.5t-13 157.5q79 -80 122 -164t26 -184q-5 -33 -20.5 -69.5t-37.5 -80.5q-10 -19 -14.5 -29t-12 -26t-9 -23.5t-3 -19t2.5 -15.5t11 -9.5t19.5 -5t30.5 2.5 t42 8q57 20 91 34t87.5 44.5t87 64t65.5 88.5t47 122q38 172 -44.5 341.5t-246.5 278.5q22 -44 43 -129q39 -159 -32 -154q-15 2 -33 9q-79 33 -120.5 100t-44 175.5t48.5 257.5q-13 -8 -34 -23.5t-72.5 -66.5t-88.5 -105.5t-60 -138t-8 -166.5q2 -12 8 -41.5t8 -43t6 -39.5 t3.5 -39.5t-1 -33.5t-6 -31.5t-13.5 -24t-21 -20.5t-31 -12q-38 -10 -67 13t-40.5 61.5t-15 81.5t10.5 75q-52 -46 -83.5 -101t-39 -107t-7.5 -85z" />
+<glyph unicode="&#xe105;" d="M-61 600l26 40q6 10 20 30t49 63.5t74.5 85.5t97 90t116.5 83.5t132.5 59t145.5 23.5t145.5 -23.5t132.5 -59t116.5 -83.5t97 -90t74.5 -85.5t49 -63.5t20 -30l26 -40l-26 -40q-6 -10 -20 -30t-49 -63.5t-74.5 -85.5t-97 -90t-116.5 -83.5t-132.5 -59t-145.5 -23.5 t-145.5 23.5t-132.5 59t-116.5 83.5t-97 90t-74.5 85.5t-49 63.5t-20 30zM120 600q7 -10 40.5 -58t56 -78.5t68 -77.5t87.5 -75t103 -49.5t125 -21.5t123.5 20t100.5 45.5t85.5 71.5t66.5 75.5t58 81.5t47 66q-1 1 -28.5 37.5t-42 55t-43.5 53t-57.5 63.5t-58.5 54 q49 -74 49 -163q0 -124 -88 -212t-212 -88t-212 88t-88 212q0 85 46 158q-102 -87 -226 -258zM377 656q49 -124 154 -191l105 105q-37 24 -75 72t-57 84l-20 36z" />
+<glyph unicode="&#xe106;" d="M-61 600l26 40q6 10 20 30t49 63.5t74.5 85.5t97 90t116.5 83.5t132.5 59t145.5 23.5q61 0 121 -17l37 142h148l-314 -1200h-148l37 143q-82 21 -165 71.5t-140 102t-109.5 112t-72 88.5t-29.5 43zM120 600q210 -282 393 -336l37 141q-107 18 -178.5 101.5t-71.5 193.5 q0 85 46 158q-102 -87 -226 -258zM377 656q49 -124 154 -191l47 47l23 87q-30 28 -59 69t-44 68l-14 26zM780 161l38 145q22 15 44.5 34t46 44t40.5 44t41 50.5t33.5 43.5t33 44t24.5 34q-97 127 -140 175l39 146q67 -54 131.5 -125.5t87.5 -103.5t36 -52l26 -40l-26 -40 q-7 -12 -25.5 -38t-63.5 -79.5t-95.5 -102.5t-124 -100t-146.5 -79z" />
+<glyph unicode="&#xe107;" d="M-97.5 34q13.5 -34 50.5 -34h1294q37 0 50.5 35.5t-7.5 67.5l-642 1056q-20 33 -48 36t-48 -29l-642 -1066q-21 -32 -7.5 -66zM155 200l445 723l445 -723h-345v100h-200v-100h-345zM500 600l100 -300l100 300v100h-200v-100z" />
+<glyph unicode="&#xe108;" d="M100 262v41q0 20 11 44.5t26 38.5l363 325v339q0 62 44 106t106 44t106 -44t44 -106v-339l363 -325q15 -14 26 -38.5t11 -44.5v-41q0 -20 -12 -26.5t-29 5.5l-359 249v-263q100 -91 100 -113v-64q0 -21 -13 -29t-32 1l-94 78h-222l-94 -78q-19 -9 -32 -1t-13 29v64 q0 22 100 113v263l-359 -249q-17 -12 -29 -5.5t-12 26.5z" />
+<glyph unicode="&#xe109;" d="M0 50q0 -20 14.5 -35t35.5 -15h1000q21 0 35.5 15t14.5 35v750h-1100v-750zM0 900h1100v150q0 21 -14.5 35.5t-35.5 14.5h-150v100h-100v-100h-500v100h-100v-100h-150q-21 0 -35.5 -14.5t-14.5 -35.5v-150zM100 100v100h100v-100h-100zM100 300v100h100v-100h-100z M100 500v100h100v-100h-100zM300 100v100h100v-100h-100zM300 300v100h100v-100h-100zM300 500v100h100v-100h-100zM500 100v100h100v-100h-100zM500 300v100h100v-100h-100zM500 500v100h100v-100h-100zM700 100v100h100v-100h-100zM700 300v100h100v-100h-100zM700 500 v100h100v-100h-100zM900 100v100h100v-100h-100zM900 300v100h100v-100h-100zM900 500v100h100v-100h-100z" />
+<glyph unicode="&#xe110;" d="M0 200v200h259l600 600h241v198l300 -295l-300 -300v197h-159l-600 -600h-341zM0 800h259l122 -122l141 142l-181 180h-341v-200zM678 381l141 142l122 -123h159v198l300 -295l-300 -300v197h-241z" />
+<glyph unicode="&#xe111;" d="M0 400v600q0 41 29.5 70.5t70.5 29.5h1000q41 0 70.5 -29.5t29.5 -70.5v-600q0 -41 -29.5 -70.5t-70.5 -29.5h-596l-304 -300v300h-100q-41 0 -70.5 29.5t-29.5 70.5z" />
+<glyph unicode="&#xe112;" d="M100 600v200h300v-250q0 -113 6 -145q17 -92 102 -117q39 -11 92 -11q37 0 66.5 5.5t50 15.5t36 24t24 31.5t14 37.5t7 42t2.5 45t0 47v25v250h300v-200q0 -42 -3 -83t-15 -104t-31.5 -116t-58 -109.5t-89 -96.5t-129 -65.5t-174.5 -25.5t-174.5 25.5t-129 65.5t-89 96.5 t-58 109.5t-31.5 116t-15 104t-3 83zM100 900v300h300v-300h-300zM800 900v300h300v-300h-300z" />
+<glyph unicode="&#xe113;" d="M-30 411l227 -227l352 353l353 -353l226 227l-578 579z" />
+<glyph unicode="&#xe114;" d="M70 797l580 -579l578 579l-226 227l-353 -353l-352 353z" />
+<glyph unicode="&#xe115;" d="M-198 700l299 283l300 -283h-203v-400h385l215 -200h-800v600h-196zM402 1000l215 -200h381v-400h-198l299 -283l299 283h-200v600h-796z" />
+<glyph unicode="&#xe116;" d="M18 939q-5 24 10 42q14 19 39 19h896l38 162q5 17 18.5 27.5t30.5 10.5h94q20 0 35 -14.5t15 -35.5t-15 -35.5t-35 -14.5h-54l-201 -961q-2 -4 -6 -10.5t-19 -17.5t-33 -11h-31v-50q0 -20 -14.5 -35t-35.5 -15t-35.5 15t-14.5 35v50h-300v-50q0 -20 -14.5 -35t-35.5 -15 t-35.5 15t-14.5 35v50h-50q-21 0 -35.5 15t-14.5 35q0 21 14.5 35.5t35.5 14.5h535l48 200h-633q-32 0 -54.5 21t-27.5 43z" />
+<glyph unicode="&#xe117;" d="M0 0v800h1200v-800h-1200zM0 900v100h200q0 41 29.5 70.5t70.5 29.5h300q41 0 70.5 -29.5t29.5 -70.5h500v-100h-1200z" />
+<glyph unicode="&#xe118;" d="M1 0l300 700h1200l-300 -700h-1200zM1 400v600h200q0 41 29.5 70.5t70.5 29.5h300q41 0 70.5 -29.5t29.5 -70.5h500v-200h-1000z" />
+<glyph unicode="&#xe119;" d="M302 300h198v600h-198l298 300l298 -300h-198v-600h198l-298 -300z" />
+<glyph unicode="&#xe120;" d="M0 600l300 298v-198h600v198l300 -298l-300 -297v197h-600v-197z" />
+<glyph unicode="&#xe121;" d="M0 100v100q0 41 29.5 70.5t70.5 29.5h1000q41 0 70.5 -29.5t29.5 -70.5v-100q0 -41 -29.5 -70.5t-70.5 -29.5h-1000q-41 0 -70.5 29.5t-29.5 70.5zM31 400l172 739q5 22 23 41.5t38 19.5h672q19 0 37.5 -22.5t23.5 -45.5l172 -732h-1138zM800 100h100v100h-100v-100z M1000 100h100v100h-100v-100z" />
+<glyph unicode="&#xe122;" d="M-101 600v50q0 24 25 49t50 38l25 13v-250l-11 5.5t-24 14t-30 21.5t-24 27.5t-11 31.5zM99 500v250v5q0 13 0.5 18.5t2.5 13t8 10.5t15 3h200l675 250v-850l-675 200h-38l47 -276q2 -12 -3 -17.5t-11 -6t-21 -0.5h-8h-83q-20 0 -34.5 14t-18.5 35q-56 337 -56 351z M1100 200v850q0 21 14.5 35.5t35.5 14.5q20 0 35 -14.5t15 -35.5v-850q0 -20 -15 -35t-35 -15q-21 0 -35.5 15t-14.5 35z" />
+<glyph unicode="&#xe123;" d="M74 350q0 21 13.5 35.5t33.5 14.5h17l118 173l63 327q15 77 76 140t144 83l-18 32q-6 19 3 32t29 13h94q20 0 29 -10.5t3 -29.5l-18 -37q83 -19 144 -82.5t76 -140.5l63 -327l118 -173h17q20 0 33.5 -14.5t13.5 -35.5q0 -20 -13 -40t-31 -27q-22 -9 -63 -23t-167.5 -37 t-251.5 -23t-245.5 20.5t-178.5 41.5l-58 20q-18 7 -31 27.5t-13 40.5zM497 110q12 -49 40 -79.5t63 -30.5t63 30.5t39 79.5q-48 -6 -102 -6t-103 6z" />
+<glyph unicode="&#xe124;" d="M21 445l233 -45l-78 -224l224 78l45 -233l155 179l155 -179l45 233l224 -78l-78 224l234 45l-180 155l180 156l-234 44l78 225l-224 -78l-45 233l-155 -180l-155 180l-45 -233l-224 78l78 -225l-233 -44l179 -156z" />
+<glyph unicode="&#xe125;" d="M0 200h200v600h-200v-600zM300 275q0 -75 100 -75h61q123 -100 139 -100h250q46 0 83 57l238 344q29 31 29 74v100q0 44 -30.5 84.5t-69.5 40.5h-328q28 118 28 125v150q0 44 -30.5 84.5t-69.5 40.5h-50q-27 0 -51 -20t-38 -48l-96 -198l-145 -196q-20 -26 -20 -63v-400z M400 300v375l150 212l100 213h50v-175l-50 -225h450v-125l-250 -375h-214l-136 100h-100z" />
+<glyph unicode="&#xe126;" d="M0 400v600h200v-600h-200zM300 525v400q0 75 100 75h61q123 100 139 100h250q46 0 83 -57l238 -344q29 -31 29 -74v-100q0 -44 -30.5 -84.5t-69.5 -40.5h-328q28 -118 28 -125v-150q0 -44 -30.5 -84.5t-69.5 -40.5h-50q-27 0 -51 20t-38 48l-96 198l-145 196 q-20 26 -20 63zM400 525l150 -212l100 -213h50v175l-50 225h450v125l-250 375h-214l-136 -100h-100v-375z" />
+<glyph unicode="&#xe127;" d="M8 200v600h200v-600h-200zM308 275v525q0 17 14 35.5t28 28.5l14 9l362 230q14 6 25 6q17 0 29 -12l109 -112q14 -14 14 -34q0 -18 -11 -32l-85 -121h302q85 0 138.5 -38t53.5 -110t-54.5 -111t-138.5 -39h-107l-130 -339q-7 -22 -20.5 -41.5t-28.5 -19.5h-341 q-7 0 -90 81t-83 94zM408 289l100 -89h293l131 339q6 21 19.5 41t28.5 20h203q16 0 25 15t9 36q0 20 -9 34.5t-25 14.5h-457h-6.5h-7.5t-6.5 0.5t-6 1t-5 1.5t-5.5 2.5t-4 4t-4 5.5q-5 12 -5 20q0 14 10 27l147 183l-86 83l-339 -236v-503z" />
+<glyph unicode="&#xe128;" d="M-101 651q0 72 54 110t139 37h302l-85 121q-11 16 -11 32q0 21 14 34l109 113q13 12 29 12q11 0 25 -6l365 -230q7 -4 16.5 -10.5t26 -26t16.5 -36.5v-526q0 -13 -85.5 -93.5t-93.5 -80.5h-342q-15 0 -28.5 20t-19.5 41l-131 339h-106q-84 0 -139 39t-55 111zM-1 601h222 q15 0 28.5 -20.5t19.5 -40.5l131 -339h293l106 89v502l-342 237l-87 -83l145 -184q10 -11 10 -26q0 -11 -5 -20q-1 -3 -3.5 -5.5l-4 -4t-5 -2.5t-5.5 -1.5t-6.5 -1t-6.5 -0.5h-7.5h-6.5h-476v-100zM999 201v600h200v-600h-200z" />
+<glyph unicode="&#xe129;" d="M97 719l230 -363q4 -6 10.5 -15.5t26 -25t36.5 -15.5h525q13 0 94 83t81 90v342q0 15 -20 28.5t-41 19.5l-339 131v106q0 84 -39 139t-111 55t-110 -53.5t-38 -138.5v-302l-121 84q-15 12 -33.5 11.5t-32.5 -13.5l-112 -110q-22 -22 -6 -53zM172 739l83 86l183 -146 q22 -18 47 -5q3 1 5.5 3.5l4 4t2.5 5t1.5 5.5t1 6.5t0.5 6v7.5v7v456q0 22 25 31t50 -0.5t25 -30.5v-202q0 -16 20 -29.5t41 -19.5l339 -130v-294l-89 -100h-503zM400 0v200h600v-200h-600z" />
+<glyph unicode="&#xe130;" d="M1 585q-15 -31 7 -53l112 -110q13 -13 32 -13.5t34 10.5l121 85l-1 -302q0 -84 38.5 -138t110.5 -54t111 55t39 139v106l339 131q20 6 40.5 19.5t20.5 28.5v342q0 7 -81 90t-94 83h-525q-17 0 -35.5 -14t-28.5 -28l-10 -15zM76 565l237 339h503l89 -100v-294l-340 -130 q-20 -6 -40 -20t-20 -29v-202q0 -22 -25 -31t-50 0t-25 31v456v14.5t-1.5 11.5t-5 12t-9.5 7q-24 13 -46 -5l-184 -146zM305 1104v200h600v-200h-600z" />
+<glyph unicode="&#xe131;" d="M5 597q0 122 47.5 232.5t127.5 190.5t190.5 127.5t232.5 47.5q162 0 299.5 -80t217.5 -218t80 -300t-80 -299.5t-217.5 -217.5t-299.5 -80t-300 80t-218 217.5t-80 299.5zM300 500h300l-2 -194l402 294l-402 298v-197h-298v-201z" />
+<glyph unicode="&#xe132;" d="M0 597q0 122 47.5 232.5t127.5 190.5t190.5 127.5t231.5 47.5q122 0 232.5 -47.5t190.5 -127.5t127.5 -190.5t47.5 -232.5q0 -162 -80 -299.5t-218 -217.5t-300 -80t-299.5 80t-217.5 217.5t-80 299.5zM200 600l400 -294v194h302v201h-300v197z" />
+<glyph unicode="&#xe133;" d="M5 597q0 122 47.5 232.5t127.5 190.5t190.5 127.5t232.5 47.5q121 0 231.5 -47.5t190.5 -127.5t127.5 -190.5t47.5 -232.5q0 -162 -80 -299.5t-217.5 -217.5t-299.5 -80t-300 80t-218 217.5t-80 299.5zM300 600h200v-300h200v300h200l-300 400z" />
+<glyph unicode="&#xe134;" d="M5 597q0 122 47.5 232.5t127.5 190.5t190.5 127.5t232.5 47.5q121 0 231.5 -47.5t190.5 -127.5t127.5 -190.5t47.5 -232.5q0 -162 -80 -299.5t-217.5 -217.5t-299.5 -80t-300 80t-218 217.5t-80 299.5zM300 600l300 -400l300 400h-200v300h-200v-300h-200z" />
+<glyph unicode="&#xe135;" d="M5 597q0 122 47.5 232.5t127.5 190.5t190.5 127.5t232.5 47.5q121 0 231.5 -47.5t190.5 -127.5t127.5 -190.5t47.5 -232.5q0 -162 -80 -299.5t-217.5 -217.5t-299.5 -80t-300 80t-218 217.5t-80 299.5zM254 780q-8 -34 5.5 -93t7.5 -87q0 -9 17 -44t16 -60q12 0 23 -5.5 t23 -15t20 -13.5q20 -10 108 -42q22 -8 53 -31.5t59.5 -38.5t57.5 -11q8 -18 -15 -55.5t-20 -57.5q12 -21 22.5 -34.5t28 -27t36.5 -17.5q0 -6 -3 -15.5t-3.5 -14.5t4.5 -17q101 -2 221 111q31 30 47 48t34 49t21 62q-14 9 -37.5 9.5t-35.5 7.5q-14 7 -49 15t-52 19 q-9 0 -39.5 -0.5t-46.5 -1.5t-39 -6.5t-39 -16.5q-50 -35 -66 -12q-4 2 -3.5 25.5t0.5 25.5q-6 13 -26.5 17t-24.5 7q2 22 -2 41t-16.5 28t-38.5 -20q-23 -25 -42 4q-19 28 -8 58q8 16 22 22q6 -1 26 -1.5t33.5 -4.5t19.5 -13q12 -19 32 -37.5t34 -27.5l14 -8q0 3 9.5 39.5 t5.5 57.5q-4 23 14.5 44.5t22.5 31.5q5 14 10 35t8.5 31t15.5 22.5t34 21.5q-6 18 10 37q8 0 23.5 -1.5t24.5 -1.5t20.5 4.5t20.5 15.5q-10 23 -30.5 42.5t-38 30t-49 26.5t-43.5 23q11 41 1 44q31 -13 58.5 -14.5t39.5 3.5l11 4q6 3
 6 -17 53.5t-64 28.5t-56 23 q-19 -3 -37 0q-15 -12 -36.5 -21t-34.5 -12t-44 -8t-39 -6q-15 -3 -46 0t-45 -3q-20 -6 -51.5 -25.5t-34.5 -34.5q-3 -11 6.5 -22.5t8.5 -18.5q-3 -34 -27.5 -91t-29.5 -79zM518 915q3 12 16 30.5t16 25.5q10 -10 18.5 -10t14 6t14.5 14.5t16 12.5q0 -18 8 -42.5t16.5 -44 t9.5 -23.5q-6 1 -39 5t-53.5 10t-36.5 16z" />
+<glyph unicode="&#xe136;" d="M0 164.5q0 21.5 15 37.5l600 599q-33 101 6 201.5t135 154.5q164 92 306 -9l-259 -138l145 -232l251 126q13 -175 -151 -267q-123 -70 -253 -23l-596 -596q-15 -16 -36.5 -16t-36.5 16l-111 110q-15 15 -15 36.5z" />
+<glyph unicode="&#xe137;" horiz-adv-x="1220" d="M0 196v100q0 41 29.5 70.5t70.5 29.5h1000q41 0 70.5 -29.5t29.5 -70.5v-100q0 -41 -29.5 -70.5t-70.5 -29.5h-1000q-41 0 -70.5 29.5t-29.5 70.5zM0 596v100q0 41 29.5 70.5t70.5 29.5h1000q41 0 70.5 -29.5t29.5 -70.5v-100q0 -41 -29.5 -70.5t-70.5 -29.5h-1000 q-41 0 -70.5 29.5t-29.5 70.5zM0 996v100q0 41 29.5 70.5t70.5 29.5h1000q41 0 70.5 -29.5t29.5 -70.5v-100q0 -41 -29.5 -70.5t-70.5 -29.5h-1000q-41 0 -70.5 29.5t-29.5 70.5zM600 596h500v100h-500v-100zM800 196h300v100h-300v-100zM900 996h200v100h-200v-100z" />
+<glyph unicode="&#xe138;" d="M100 1100v100h1000v-100h-1000zM150 1000h900l-350 -500v-300l-200 -200v500z" />
+<glyph unicode="&#xe139;" d="M0 200v200h1200v-200q0 -41 -29.5 -70.5t-70.5 -29.5h-1000q-41 0 -70.5 29.5t-29.5 70.5zM0 500v400q0 41 29.5 70.5t70.5 29.5h300v100q0 41 29.5 70.5t70.5 29.5h200q41 0 70.5 -29.5t29.5 -70.5v-100h300q41 0 70.5 -29.5t29.5 -70.5v-400h-500v100h-200v-100h-500z M500 1000h200v100h-200v-100z" />
+<glyph unicode="&#xe140;" d="M0 0v400l129 -129l200 200l142 -142l-200 -200l129 -129h-400zM0 800l129 129l200 -200l142 142l-200 200l129 129h-400v-400zM729 329l142 142l200 -200l129 129v-400h-400l129 129zM729 871l200 200l-129 129h400v-400l-129 129l-200 -200z" />
+<glyph unicode="&#xe141;" d="M0 596q0 162 80 299t217 217t299 80t299 -80t217 -217t80 -299t-80 -299t-217 -217t-299 -80t-299 80t-217 217t-80 299zM182 596q0 -172 121.5 -293t292.5 -121t292.5 121t121.5 293q0 171 -121.5 292.5t-292.5 121.5t-292.5 -121.5t-121.5 -292.5zM291 655 q0 23 15.5 38.5t38.5 15.5t39 -16t16 -38q0 -23 -16 -39t-39 -16q-22 0 -38 16t-16 39zM400 850q0 22 16 38.5t39 16.5q22 0 38 -16t16 -39t-16 -39t-38 -16q-23 0 -39 16.5t-16 38.5zM513 609q0 32 21 56.5t52 29.5l122 126l1 1q-9 14 -9 28q0 22 16 38.5t39 16.5 q22 0 38 -16t16 -39t-16 -39t-38 -16q-16 0 -29 10l-55 -145q17 -22 17 -51q0 -36 -25.5 -61.5t-61.5 -25.5q-37 0 -62.5 25.5t-25.5 61.5zM800 655q0 22 16 38t39 16t38.5 -15.5t15.5 -38.5t-16 -39t-38 -16q-23 0 -39 16t-16 39z" />
+<glyph unicode="&#xe142;" d="M-40 375q-13 -95 35 -173q35 -57 94 -89t129 -32q63 0 119 28q33 16 65 40.5t52.5 45.5t59.5 64q40 44 57 61l394 394q35 35 47 84t-3 96q-27 87 -117 104q-20 2 -29 2q-46 0 -79.5 -17t-67.5 -51l-388 -396l-7 -7l69 -67l377 373q20 22 39 38q23 23 50 23q38 0 53 -36 q16 -39 -20 -75l-547 -547q-52 -52 -125 -52q-55 0 -100 33t-54 96q-5 35 2.5 66t31.5 63t42 50t56 54q24 21 44 41l348 348q52 52 82.5 79.5t84 54t107.5 26.5q25 0 48 -4q95 -17 154 -94.5t51 -175.5q-7 -101 -98 -192l-252 -249l-253 -256l7 -7l69 -60l517 511 q67 67 95 157t11 183q-16 87 -67 154t-130 103q-69 33 -152 33q-107 0 -197 -55q-40 -24 -111 -95l-512 -512q-68 -68 -81 -163z" />
+<glyph unicode="&#xe143;" d="M79 784q0 131 99 229.5t230 98.5q144 0 242 -129q103 129 245 129q130 0 227 -98.5t97 -229.5q0 -46 -17.5 -91t-61 -99t-77 -89.5t-104.5 -105.5q-197 -191 -293 -322l-17 -23l-16 23q-43 58 -100 122.5t-92 99.5t-101 100l-84.5 84.5t-68 74t-60 78t-33.5 70.5t-15 78z M250 784q0 -27 30.5 -70t61.5 -75.5t95 -94.5l22 -22q93 -90 190 -201q82 92 195 203l12 12q64 62 97.5 97t64.5 79t31 72q0 71 -48 119.5t-106 48.5q-73 0 -131 -83l-118 -171l-114 174q-51 80 -124 80q-59 0 -108.5 -49.5t-49.5 -118.5z" />
+<glyph unicode="&#xe144;" d="M57 353q0 -94 66 -160l141 -141q66 -66 159 -66q95 0 159 66l283 283q66 66 66 159t-66 159l-141 141q-12 12 -19 17l-105 -105l212 -212l-389 -389l-247 248l95 95l-18 18q-46 45 -75 101l-55 -55q-66 -66 -66 -159zM269 706q0 -93 66 -159l141 -141l19 -17l105 105 l-212 212l389 389l247 -247l-95 -96l18 -18q46 -46 77 -99l29 29q35 35 62.5 88t27.5 96q0 93 -66 159l-141 141q-66 66 -159 66q-95 0 -159 -66l-283 -283q-66 -64 -66 -159z" />
+<glyph unicode="&#xe145;" d="M200 100v953q0 21 30 46t81 48t129 38t163 15t162 -15t127 -38t79 -48t29 -46v-953q0 -41 -29.5 -70.5t-70.5 -29.5h-600q-41 0 -70.5 29.5t-29.5 70.5zM300 300h600v700h-600v-700zM496 150q0 -43 30.5 -73.5t73.5 -30.5t73.5 30.5t30.5 73.5t-30.5 73.5t-73.5 30.5 t-73.5 -30.5t-30.5 -73.5z" />
+<glyph unicode="&#xe146;" d="M0 0l303 380l207 208l-210 212h300l267 279l-35 36q-15 14 -15 35t15 35q14 15 35 15t35 -15l283 -282q15 -15 15 -36t-15 -35q-14 -15 -35 -15t-35 15l-36 35l-279 -267v-300l-212 210l-208 -207z" />
+<glyph unicode="&#xe148;" d="M295 433h139q5 -77 48.5 -126.5t117.5 -64.5v335l-27 7q-46 14 -79 26.5t-72 36t-62.5 52t-40 72.5t-16.5 99q0 92 44 159.5t109 101t144 40.5v78h100v-79q38 -4 72.5 -13.5t75.5 -31.5t71 -53.5t51.5 -84t24.5 -118.5h-159q-8 72 -35 109.5t-101 50.5v-307l64 -14 q34 -7 64 -16.5t70 -31.5t67.5 -52t47.5 -80.5t20 -112.5q0 -139 -89 -224t-244 -96v-77h-100v78q-152 17 -237 104q-40 40 -52.5 93.5t-15.5 139.5zM466 889q0 -29 8 -51t16.5 -34t29.5 -22.5t31 -13.5t38 -10q7 -2 11 -3v274q-61 -8 -97.5 -37.5t-36.5 -102.5zM700 237 q170 18 170 151q0 64 -44 99.5t-126 60.5v-311z" />
+<glyph unicode="&#xe149;" d="M100 600v100h166q-24 49 -44 104q-10 26 -14.5 55.5t-3 72.5t25 90t68.5 87q97 88 263 88q129 0 230 -89t101 -208h-153q0 52 -34 89.5t-74 51.5t-76 14q-37 0 -79 -14.5t-62 -35.5q-41 -44 -41 -101q0 -11 2.5 -24.5t5.5 -24t9.5 -26.5t10.5 -25t14 -27.5t14 -25.5 t15.5 -27t13.5 -24h242v-100h-197q8 -50 -2.5 -115t-31.5 -94q-41 -59 -99 -113q35 11 84 18t70 7q32 1 102 -16t104 -17q76 0 136 30l50 -147q-41 -25 -80.5 -36.5t-59 -13t-61.5 -1.5q-23 0 -128 33t-155 29q-39 -4 -82 -17t-66 -25l-24 -11l-55 145l16.5 11t15.5 10 t13.5 9.5t14.5 12t14.5 14t17.5 18.5q48 55 54 126.5t-30 142.5h-221z" />
+<glyph unicode="&#xe150;" d="M2 300l298 -300l298 300h-198v900h-200v-900h-198zM602 900l298 300l298 -300h-198v-900h-200v900h-198z" />
+<glyph unicode="&#xe151;" d="M2 300h198v900h200v-900h198l-298 -300zM700 0v200h100v-100h200v-100h-300zM700 400v100h300v-200h-99v-100h-100v100h99v100h-200zM700 700v500h300v-500h-100v100h-100v-100h-100zM801 900h100v200h-100v-200z" />
+<glyph unicode="&#xe152;" d="M2 300h198v900h200v-900h198l-298 -300zM700 0v500h300v-500h-100v100h-100v-100h-100zM700 700v200h100v-100h200v-100h-300zM700 1100v100h300v-200h-99v-100h-100v100h99v100h-200zM801 200h100v200h-100v-200z" />
+<glyph unicode="&#xe153;" d="M2 300l298 -300l298 300h-198v900h-200v-900h-198zM800 100v400h300v-500h-100v100h-200zM800 1100v100h200v-500h-100v400h-100zM901 200h100v200h-100v-200z" />
+<glyph unicode="&#xe154;" d="M2 300l298 -300l298 300h-198v900h-200v-900h-198zM800 400v100h200v-500h-100v400h-100zM800 800v400h300v-500h-100v100h-200zM901 900h100v200h-100v-200z" />
+<glyph unicode="&#xe155;" d="M2 300l298 -300l298 300h-198v900h-200v-900h-198zM700 100v200h500v-200h-500zM700 400v200h400v-200h-400zM700 700v200h300v-200h-300zM700 1000v200h200v-200h-200z" />
+<glyph unicode="&#xe156;" d="M2 300l298 -300l298 300h-198v900h-200v-900h-198zM700 100v200h200v-200h-200zM700 400v200h300v-200h-300zM700 700v200h400v-200h-400zM700 1000v200h500v-200h-500z" />
+<glyph unicode="&#xe157;" d="M0 400v300q0 165 117.5 282.5t282.5 117.5h300q162 0 281 -118.5t119 -281.5v-300q0 -165 -118.5 -282.5t-281.5 -117.5h-300q-165 0 -282.5 117.5t-117.5 282.5zM200 300q0 -41 29.5 -70.5t70.5 -29.5h500q41 0 70.5 29.5t29.5 70.5v500q0 41 -29.5 70.5t-70.5 29.5 h-500q-41 0 -70.5 -29.5t-29.5 -70.5v-500z" />
+<glyph unicode="&#xe158;" d="M0 400v300q0 163 119 281.5t281 118.5h300q165 0 282.5 -117.5t117.5 -282.5v-300q0 -165 -117.5 -282.5t-282.5 -117.5h-300q-163 0 -281.5 117.5t-118.5 282.5zM200 300q0 -41 29.5 -70.5t70.5 -29.5h500q41 0 70.5 29.5t29.5 70.5v500q0 41 -29.5 70.5t-70.5 29.5 h-500q-41 0 -70.5 -29.5t-29.5 -70.5v-500zM400 300l333 250l-333 250v-500z" />
+<glyph unicode="&#xe159;" d="M0 400v300q0 163 117.5 281.5t282.5 118.5h300q163 0 281.5 -119t118.5 -281v-300q0 -165 -117.5 -282.5t-282.5 -117.5h-300q-165 0 -282.5 117.5t-117.5 282.5zM200 300q0 -41 29.5 -70.5t70.5 -29.5h500q41 0 70.5 29.5t29.5 70.5v500q0 41 -29.5 70.5t-70.5 29.5 h-500q-41 0 -70.5 -29.5t-29.5 -70.5v-500zM300 700l250 -333l250 333h-500z" />
+<glyph unicode="&#xe160;" d="M0 400v300q0 165 117.5 282.5t282.5 117.5h300q165 0 282.5 -117.5t117.5 -282.5v-300q0 -162 -118.5 -281t-281.5 -119h-300q-165 0 -282.5 118.5t-117.5 281.5zM200 300q0 -41 29.5 -70.5t70.5 -29.5h500q41 0 70.5 29.5t29.5 70.5v500q0 41 -29.5 70.5t-70.5 29.5 h-500q-41 0 -70.5 -29.5t-29.5 -70.5v-500zM300 400h500l-250 333z" />
+<glyph unicode="&#xe161;" d="M0 400v300h300v200l400 -350l-400 -350v200h-300zM500 0v200h500q41 0 70.5 29.5t29.5 70.5v500q0 41 -29.5 70.5t-70.5 29.5h-500v200h400q165 0 282.5 -117.5t117.5 -282.5v-300q0 -165 -117.5 -282.5t-282.5 -117.5h-400z" />
+<glyph unicode="&#xe162;" d="M216 519q10 -19 32 -19h302q-155 -438 -160 -458q-5 -21 4 -32l9 -8l9 -1q13 0 26 16l538 630q15 19 6 36q-8 18 -32 16h-300q1 4 78 219.5t79 227.5q2 17 -6 27l-8 8h-9q-16 0 -25 -15q-4 -5 -98.5 -111.5t-228 -257t-209.5 -238.5q-17 -19 -7 -40z" />
+<glyph unicode="&#xe163;" d="M0 400q0 -165 117.5 -282.5t282.5 -117.5h300q47 0 100 15v185h-500q-41 0 -70.5 29.5t-29.5 70.5v500q0 41 29.5 70.5t70.5 29.5h500v185q-14 4 -114 7.5t-193 5.5l-93 2q-165 0 -282.5 -117.5t-117.5 -282.5v-300zM600 400v300h300v200l400 -350l-400 -350v200h-300z " />
+<glyph unicode="&#xe164;" d="M0 400q0 -165 117.5 -282.5t282.5 -117.5h300q163 0 281.5 117.5t118.5 282.5v98l-78 73l-122 -123v-148q0 -41 -29.5 -70.5t-70.5 -29.5h-500q-41 0 -70.5 29.5t-29.5 70.5v500q0 41 29.5 70.5t70.5 29.5h156l118 122l-74 78h-100q-165 0 -282.5 -117.5t-117.5 -282.5 v-300zM496 709l353 342l-149 149h500v-500l-149 149l-342 -353z" />
+<glyph unicode="&#xe165;" d="M4 600q0 162 80 299t217 217t299 80t299 -80t217 -217t80 -299t-80 -299t-217 -217t-299 -80t-299 80t-217 217t-80 299zM186 600q0 -171 121.5 -292.5t292.5 -121.5t292.5 121.5t121.5 292.5t-121.5 292.5t-292.5 121.5t-292.5 -121.5t-121.5 -292.5zM406 600 q0 80 57 137t137 57t137 -57t57 -137t-57 -137t-137 -57t-137 57t-57 137z" />
+<glyph unicode="&#xe166;" d="M0 0v275q0 11 7 18t18 7h1048q11 0 19 -7.5t8 -17.5v-275h-1100zM100 800l445 -500l450 500h-295v400h-300v-400h-300zM900 150h100v50h-100v-50z" />
+<glyph unicode="&#xe167;" d="M0 0v275q0 11 7 18t18 7h1048q11 0 19 -7.5t8 -17.5v-275h-1100zM100 700h300v-300h300v300h295l-445 500zM900 150h100v50h-100v-50z" />
+<glyph unicode="&#xe168;" d="M0 0v275q0 11 7 18t18 7h1048q11 0 19 -7.5t8 -17.5v-275h-1100zM100 705l305 -305l596 596l-154 155l-442 -442l-150 151zM900 150h100v50h-100v-50z" />
+<glyph unicode="&#xe169;" d="M0 0v275q0 11 7 18t18 7h1048q11 0 19 -7.5t8 -17.5v-275h-1100zM100 988l97 -98l212 213l-97 97zM200 401h700v699l-250 -239l-149 149l-212 -212l149 -149zM900 150h100v50h-100v-50z" />
+<glyph unicode="&#xe170;" d="M0 0v275q0 11 7 18t18 7h1048q11 0 19 -7.5t8 -17.5v-275h-1100zM200 612l212 -212l98 97l-213 212zM300 1200l239 -250l-149 -149l212 -212l149 148l248 -237v700h-699zM900 150h100v50h-100v-50z" />
+<glyph unicode="&#xe171;" d="M23 415l1177 784v-1079l-475 272l-310 -393v416h-392zM494 210l672 938l-672 -712v-226z" />
+<glyph unicode="&#xe172;" d="M0 150v1000q0 20 14.5 35t35.5 15h250v-300h500v300h100l200 -200v-850q0 -21 -15 -35.5t-35 -14.5h-150v400h-700v-400h-150q-21 0 -35.5 14.5t-14.5 35.5zM600 1000h100v200h-100v-200z" />
+<glyph unicode="&#xe173;" d="M0 150v1000q0 20 14.5 35t35.5 15h250v-300h500v300h100l200 -200v-218l-276 -275l-120 120l-126 -127h-378v-400h-150q-21 0 -35.5 14.5t-14.5 35.5zM581 306l123 123l120 -120l353 352l123 -123l-475 -476zM600 1000h100v200h-100v-200z" />
+<glyph unicode="&#xe174;" d="M0 150v1000q0 20 14.5 35t35.5 15h250v-300h500v300h100l200 -200v-269l-103 -103l-170 170l-298 -298h-329v-400h-150q-21 0 -35.5 14.5t-14.5 35.5zM600 1000h100v200h-100v-200zM700 133l170 170l-170 170l127 127l170 -170l170 170l127 -128l-170 -169l170 -170 l-127 -127l-170 170l-170 -170z" />
+<glyph unicode="&#xe175;" d="M0 150v1000q0 20 14.5 35t35.5 15h250v-300h500v300h100l200 -200v-300h-400v-200h-500v-400h-150q-21 0 -35.5 14.5t-14.5 35.5zM600 300l300 -300l300 300h-200v300h-200v-300h-200zM600 1000v200h100v-200h-100z" />
+<glyph unicode="&#xe176;" d="M0 150v1000q0 20 14.5 35t35.5 15h250v-300h500v300h100l200 -200v-402l-200 200l-298 -298h-402v-400h-150q-21 0 -35.5 14.5t-14.5 35.5zM600 300h200v-300h200v300h200l-300 300zM600 1000v200h100v-200h-100z" />
+<glyph unicode="&#xe177;" d="M0 250q0 -21 14.5 -35.5t35.5 -14.5h1100q21 0 35.5 14.5t14.5 35.5v550h-1200v-550zM0 900h1200v150q0 21 -14.5 35.5t-35.5 14.5h-1100q-21 0 -35.5 -14.5t-14.5 -35.5v-150zM100 300v200h400v-200h-400z" />
+<glyph unicode="&#xe178;" d="M0 400l300 298v-198h400v-200h-400v-198zM100 800v200h100v-200h-100zM300 800v200h100v-200h-100zM500 800v200h400v198l300 -298l-300 -298v198h-400zM800 300v200h100v-200h-100zM1000 300h100v200h-100v-200z" />
+<glyph unicode="&#xe179;" d="M100 700v400l50 100l50 -100v-300h100v300l50 100l50 -100v-300h100v300l50 100l50 -100v-400l-100 -203v-447q0 -21 -14.5 -35.5t-35.5 -14.5h-200q-21 0 -35.5 14.5t-14.5 35.5v447zM800 597q0 -29 10.5 -55.5t25 -43t29 -28.5t25.5 -18l10 -5v-397q0 -21 14.5 -35.5 t35.5 -14.5h200q21 0 35.5 14.5t14.5 35.5v1106q0 31 -18 40.5t-44 -7.5l-276 -117q-25 -16 -43.5 -50.5t-18.5 -65.5v-359z" />
+<glyph unicode="&#xe180;" d="M100 0h400v56q-75 0 -87.5 6t-12.5 44v394h500v-394q0 -38 -12.5 -44t-87.5 -6v-56h400v56q-4 0 -11 0.5t-24 3t-30 7t-24 15t-11 24.5v888q0 22 25 34.5t50 13.5l25 2v56h-400v-56q75 0 87.5 -6t12.5 -44v-394h-500v394q0 38 12.5 44t87.5 6v56h-400v-56q4 0 11 -0.5 t24 -3t30 -7t24 -15t11 -24.5v-888q0 -22 -25 -34.5t-50 -13.5l-25 -2v-56z" />
+<glyph unicode="&#xe181;" d="M0 300q0 -41 29.5 -70.5t70.5 -29.5h300q41 0 70.5 29.5t29.5 70.5v500q0 41 -29.5 70.5t-70.5 29.5h-300q-41 0 -70.5 -29.5t-29.5 -70.5v-500zM100 100h400l200 200h105l295 98v-298h-425l-100 -100h-375zM100 300v200h300v-200h-300zM100 600v200h300v-200h-300z M100 1000h400l200 -200v-98l295 98h105v200h-425l-100 100h-375zM700 402v163l400 133v-163z" />
+<glyph unicode="&#xe182;" d="M16.5 974.5q0.5 -21.5 16 -90t46.5 -140t104 -177.5t175 -208q103 -103 207.5 -176t180 -103.5t137 -47t92.5 -16.5l31 1l163 162q16 17 13 40.5t-22 37.5l-192 136q-19 14 -45 12t-42 -19l-119 -118q-143 103 -267 227q-126 126 -227 268l118 118q17 17 20 41.5 t-11 44.5l-139 194q-14 19 -36.5 22t-40.5 -14l-162 -162q-1 -11 -0.5 -32.5z" />
+<glyph unicode="&#xe183;" d="M0 50v212q0 20 10.5 45.5t24.5 39.5l365 303v50q0 4 1 10.5t12 22.5t30 28.5t60 23t97 10.5t97 -10t60 -23.5t30 -27.5t12 -24l1 -10v-50l365 -303q14 -14 24.5 -39.5t10.5 -45.5v-212q0 -21 -15 -35.5t-35 -14.5h-1100q-21 0 -35.5 14.5t-14.5 35.5zM0 712 q0 -21 14.5 -33.5t34.5 -8.5l202 33q20 4 34.5 21t14.5 38v146q141 24 300 24t300 -24v-146q0 -21 14.5 -38t34.5 -21l202 -33q20 -4 34.5 8.5t14.5 33.5v200q-6 8 -19 20.5t-63 45t-112 57t-171 45t-235 20.5q-92 0 -175 -10.5t-141.5 -27t-108.5 -36.5t-81.5 -40 t-53.5 -36.5t-31 -27.5l-9 -10v-200z" />
+<glyph unicode="&#xe184;" d="M100 0v100h1100v-100h-1100zM175 200h950l-125 150v250l100 100v400h-100v-200h-100v200h-200v-200h-100v200h-200v-200h-100v200h-100v-400l100 -100v-250z" />
+<glyph unicode="&#xe185;" d="M100 0h300v400q0 41 -29.5 70.5t-70.5 29.5h-100q-41 0 -70.5 -29.5t-29.5 -70.5v-400zM500 0v1000q0 41 29.5 70.5t70.5 29.5h100q41 0 70.5 -29.5t29.5 -70.5v-1000h-300zM900 0v700q0 41 29.5 70.5t70.5 29.5h100q41 0 70.5 -29.5t29.5 -70.5v-700h-300z" />
+<glyph unicode="&#xe186;" d="M-100 300v500q0 124 88 212t212 88h700q124 0 212 -88t88 -212v-500q0 -124 -88 -212t-212 -88h-700q-124 0 -212 88t-88 212zM100 200h900v700h-900v-700zM200 300h300v300h-200v100h200v100h-300v-300h200v-100h-200v-100zM600 300h200v100h100v300h-100v100h-200v-500 zM700 400v300h100v-300h-100z" />
+<glyph unicode="&#xe187;" d="M-100 300v500q0 124 88 212t212 88h700q124 0 212 -88t88 -212v-500q0 -124 -88 -212t-212 -88h-700q-124 0 -212 88t-88 212zM100 200h900v700h-900v-700zM200 300h100v200h100v-200h100v500h-100v-200h-100v200h-100v-500zM600 300h200v100h100v300h-100v100h-200v-500 zM700 400v300h100v-300h-100z" />
+<glyph unicode="&#xe188;" d="M-100 300v500q0 124 88 212t212 88h700q124 0 212 -88t88 -212v-500q0 -124 -88 -212t-212 -88h-700q-124 0 -212 88t-88 212zM100 200h900v700h-900v-700zM200 300h300v100h-200v300h200v100h-300v-500zM600 300h300v100h-200v300h200v100h-300v-500z" />
+<glyph unicode="&#xe189;" d="M-100 300v500q0 124 88 212t212 88h700q124 0 212 -88t88 -212v-500q0 -124 -88 -212t-212 -88h-700q-124 0 -212 88t-88 212zM100 200h900v700h-900v-700zM200 550l300 -150v300zM600 400l300 150l-300 150v-300z" />
+<glyph unicode="&#xe190;" d="M-100 300v500q0 124 88 212t212 88h700q124 0 212 -88t88 -212v-500q0 -124 -88 -212t-212 -88h-700q-124 0 -212 88t-88 212zM100 200h900v700h-900v-700zM200 300v500h700v-500h-700zM300 400h130q41 0 68 42t27 107t-28.5 108t-66.5 43h-130v-300zM575 549 q0 -65 27 -107t68 -42h130v300h-130q-38 0 -66.5 -43t-28.5 -108z" />
+<glyph unicode="&#xe191;" d="M-100 300v500q0 124 88 212t212 88h700q124 0 212 -88t88 -212v-500q0 -124 -88 -212t-212 -88h-700q-124 0 -212 88t-88 212zM100 200h900v700h-900v-700zM200 300h300v300h-200v100h200v100h-300v-300h200v-100h-200v-100zM601 300h100v100h-100v-100zM700 700h100 v-400h100v500h-200v-100z" />
+<glyph unicode="&#xe192;" d="M-100 300v500q0 124 88 212t212 88h700q124 0 212 -88t88 -212v-500q0 -124 -88 -212t-212 -88h-700q-124 0 -212 88t-88 212zM100 200h900v700h-900v-700zM200 300h300v400h-200v100h-100v-500zM301 400v200h100v-200h-100zM601 300h100v100h-100v-100zM700 700h100 v-400h100v500h-200v-100z" />
+<glyph unicode="&#xe193;" d="M-100 300v500q0 124 88 212t212 88h700q124 0 212 -88t88 -212v-500q0 -124 -88 -212t-212 -88h-700q-124 0 -212 88t-88 212zM100 200h900v700h-900v-700zM200 700v100h300v-300h-99v-100h-100v100h99v200h-200zM201 300v100h100v-100h-100zM601 300v100h100v-100h-100z M700 700v100h200v-500h-100v400h-100z" />
+<glyph unicode="&#xe194;" d="M4 600q0 162 80 299t217 217t299 80t299 -80t217 -217t80 -299t-80 -299t-217 -217t-299 -80t-299 80t-217 217t-80 299zM186 600q0 -171 121.5 -292.5t292.5 -121.5t292.5 121.5t121.5 292.5t-121.5 292.5t-292.5 121.5t-292.5 -121.5t-121.5 -292.5zM400 500v200 l100 100h300v-100h-300v-200h300v-100h-300z" />
+<glyph unicode="&#xe195;" d="M0 600q0 162 80 299t217 217t299 80t299 -80t217 -217t80 -299t-80 -299t-217 -217t-299 -80t-299 80t-217 217t-80 299zM182 600q0 -171 121.5 -292.5t292.5 -121.5t292.5 121.5t121.5 292.5t-121.5 292.5t-292.5 121.5t-292.5 -121.5t-121.5 -292.5zM400 400v400h300 l100 -100v-100h-100v100h-200v-100h200v-100h-200v-100h-100zM700 400v100h100v-100h-100z" />
+<glyph unicode="&#xe197;" d="M-14 494q0 -80 56.5 -137t135.5 -57h222v300h400v-300h128q120 0 205 86t85 208q0 120 -85 206.5t-205 86.5q-46 0 -90 -14q-44 97 -134.5 156.5t-200.5 59.5q-152 0 -260 -107.5t-108 -260.5q0 -25 2 -37q-66 -14 -108.5 -67.5t-42.5 -122.5zM300 200h200v300h200v-300 h200l-300 -300z" />
+<glyph unicode="&#xe198;" d="M-14 494q0 -80 56.5 -137t135.5 -57h8l414 414l403 -403q94 26 154.5 104t60.5 178q0 121 -85 207.5t-205 86.5q-46 0 -90 -14q-44 97 -134.5 156.5t-200.5 59.5q-152 0 -260 -107.5t-108 -260.5q0 -25 2 -37q-66 -14 -108.5 -67.5t-42.5 -122.5zM300 200l300 300 l300 -300h-200v-300h-200v300h-200z" />
+<glyph unicode="&#xe199;" d="M100 200h400v-155l-75 -45h350l-75 45v155h400l-270 300h170l-270 300h170l-300 333l-300 -333h170l-270 -300h170z" />
+<glyph unicode="&#xe200;" d="M121 700q0 -53 28.5 -97t75.5 -65q-4 -16 -4 -38q0 -74 52.5 -126.5t126.5 -52.5q56 0 100 30v-306l-75 -45h350l-75 45v306q46 -30 100 -30q74 0 126.5 52.5t52.5 126.5q0 24 -9 55q50 32 79.5 83t29.5 112q0 90 -61.5 155.5t-150.5 71.5q-26 89 -99.5 145.5 t-167.5 56.5q-116 0 -197.5 -81.5t-81.5 -197.5q0 -4 1 -12t1 -11q-14 2 -23 2q-74 0 -126.5 -52.5t-52.5 -126.5z" />
+</font>
+</defs></svg> 
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/ambari/blob/5eb22214/contrib/views/pig/src/main/resources/ui/pig-web/app/controllers/edit.js
----------------------------------------------------------------------
diff --git a/contrib/views/pig/src/main/resources/ui/pig-web/app/controllers/edit.js b/contrib/views/pig/src/main/resources/ui/pig-web/app/controllers/edit.js
new file mode 100644
index 0000000..e2e9a70
--- /dev/null
+++ b/contrib/views/pig/src/main/resources/ui/pig-web/app/controllers/edit.js
@@ -0,0 +1,165 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+var App = require('app');
+
+App.EditController = Em.ObjectController.extend({
+  pigArgumentsPull: Em.A(),
+  isExec:false,
+  actions:{
+    addArgument:function (arg) {
+      if (!arg) {
+        return false;
+      };
+      var pull = this.get('pigArgumentsPull');
+      if (Em.$.inArray(arg,pull)<0) {
+        pull.pushObject(arg);
+      } else {
+        this.send('showAlert', {'message': Em.I18n.t('scripts.alert.arg_present'), status:'info'});
+      }
+    },
+    removeArgument:function (arg) {
+      var index = this.pigArgumentsPull.indexOf(arg.toString());
+      this.pigArgumentsPull.removeAt(index);
+    },
+    execute: function (object, operation) {
+      var controller = this,
+          job,
+          sendAlert = function (status) {
+            var alerts = {success:Em.I18n.t('job.alert.job_started'), error:Em.I18n.t('job.alert.start_filed')};
+            return function (argument) {
+              controller.set('isExec',false);
+              controller.send('showAlert', {message:alerts[status],status:status});
+              if (status=='success') {
+                controller.transitionToRoute('job',job);
+              };
+            };
+          };
+
+      controller.set('isExec',true);
+
+      return Ember.RSVP.resolve(object.get('pigScript')).then(function (file) {
+        var savePromises = [file.save()];
+
+        job = controller.prepareJob(file, object, operation);
+
+        if (object.get('constructor.typeKey') === "script") {
+          savePromises.push(object.save());
+        };
+
+        return Ember.RSVP.all(savePromises).then(function () {
+          return job.save().then(sendAlert('success'),sendAlert('error'));
+        });
+      });
+    },
+  },
+  prepareJob:function (file, object, operation) {
+    var controller = this,
+        args = object.get('templetonArguments'),
+        parameters = this.get('pigParams.length') > 0,
+        pigParams = this.get('pigParams') || [],
+        fileContent = file.get('fileContent'),
+        config;
+
+    pigParams.forEach(function (param) {
+      var rgParam = new RegExp(param.param,'g');
+      fileContent = fileContent.replace(rgParam,param.value);
+    });
+    
+    if (operation === 'execute') {
+      config = {
+        templetonArguments: args,
+        title: object.get('title'),
+        forcedContent: (parameters)? fileContent:null,
+        pigScript: (!parameters)?file:null
+      };
+    } else if (operation === 'explain') {
+      config = {
+        templetonArguments:  '',
+        title: 'Explain: "' + object.get('title') + '"',
+        jobType: 'explain',
+        sourceFileContent: (parameters)? fileContent:null,
+        sourceFile: (!parameters)?file.get('id'):null,
+        forcedContent: 'explain -script ${sourceFile}'
+      }
+    } else {
+      config = {
+        templetonArguments: (!args.match(/-check/g))?args+(args?"\t":"")+'-check':args,
+        title: 'Syntax check: "' + object.get('title') + '"',
+        jobType:  'syntax_check',
+        forcedContent: (parameters)? fileContent:null,
+        pigScript: (!parameters)?file:null
+      }
+    };
+    
+    if (object.get('constructor.typeKey') === 'script'){
+      config.scriptId = object.get('id');
+    } else {
+      config.scriptId = (operation != 'explain')?object.get('scriptId'):null;
+    };
+
+    return this.store.createRecord('job',config);
+  },
+  /*
+   *Is script or scritp file is dirty.
+   * @return {boolean}
+   */
+  scriptDirty:function () {
+    return this.get('content.isDirty') || this.get('content.pigScript.isDirty');
+  }.property('content.pigScript.isDirty','content.isDirty'),
+
+  /**
+   * Is script is in error state.
+   * @return {boolean}
+   */
+  scriptError:function () {
+    return this.get('content.isError');
+  }.property('content.isError'),
+
+  /*
+    Gets script arguments array from pigArgumentsPull
+    and write to model as string
+  */
+  pigArgToString:function (controller,observer) {
+    var args = controller.get('pigArgumentsPull');
+    var oldargs = (this.get('content.templetonArguments'))?this.get('content.templetonArguments').w():[];
+    if (args.length != oldargs.length) {
+      this.set('content.templetonArguments',args.join('\t'));
+    };
+  }.observes('pigArgumentsPull.@each'),
+
+  /*
+    get script arguments string from model
+    and write to pigArgumentsPull as array
+  */
+  pigArgToArray:function (controller,observer) {
+    var args =  controller.get(observer);
+    if (args && args.length > 0){
+      controller.set('pigArgumentsPull',args.w());
+    }
+  }.observes('content.templetonArguments'),
+
+  /**
+   * available UDFs
+   * @return {App.Udf} promise
+   */
+  ufdsList:function () {
+    return this.store.find('udf');
+  }.property('udf'),
+
+});

http://git-wip-us.apache.org/repos/asf/ambari/blob/5eb22214/contrib/views/pig/src/main/resources/ui/pig-web/app/controllers/jobResults.js
----------------------------------------------------------------------
diff --git a/contrib/views/pig/src/main/resources/ui/pig-web/app/controllers/jobResults.js b/contrib/views/pig/src/main/resources/ui/pig-web/app/controllers/jobResults.js
new file mode 100644
index 0000000..50073e2
--- /dev/null
+++ b/contrib/views/pig/src/main/resources/ui/pig-web/app/controllers/jobResults.js
@@ -0,0 +1,58 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+var App = require('app');
+
+App.JobResultsController = Em.ObjectController.extend({
+  getOutputProxy:function (output) {
+    var self = this,
+        promise,
+        result;
+
+    var host = this.store.adapterFor('application').get('host');
+    var namespace = this.store.adapterFor('application').get('namespace');
+    var jobId = this.get('content.id');
+    var url = [host, namespace,'jobs',jobId, 'results',output].join('/');
+
+    promise = new Ember.RSVP.Promise(function(resolve,reject){
+      return Em.$.getJSON(url).then(function (stdoutFile) {
+        resolve(stdoutFile.file);
+      },function (error) {
+        var responseText = JSON.parse(error.responseText);
+        self.send('showAlert', {'message': Em.I18n.t('job.alert.'+output+'_error',
+          {status:responseText.status, message:responseText.message}), status:'error'});
+      })
+    });
+
+    return Ember.ObjectProxy.extend(Ember.PromiseProxyMixin).create({
+      promise: promise
+    });
+  },
+  checkStatus:function (argument) {
+    return (this.get('content.status')=='COMPLETED')?true:false;
+  },
+  stdout:function() {
+    return (this.checkStatus())?this.getOutputProxy('stdout'):null;
+  }.property(),
+  stderr:function() {
+    return (this.checkStatus())?this.getOutputProxy('stderr'):null;
+  }.property(),
+  exitcode:function() {
+    return (this.checkStatus())?this.getOutputProxy('exit'):null;
+  }.property()
+});

http://git-wip-us.apache.org/repos/asf/ambari/blob/5eb22214/contrib/views/pig/src/main/resources/ui/pig-web/app/controllers/modal/pigModal.js
----------------------------------------------------------------------
diff --git a/contrib/views/pig/src/main/resources/ui/pig-web/app/controllers/modal/pigModal.js b/contrib/views/pig/src/main/resources/ui/pig-web/app/controllers/modal/pigModal.js
new file mode 100644
index 0000000..85411af
--- /dev/null
+++ b/contrib/views/pig/src/main/resources/ui/pig-web/app/controllers/modal/pigModal.js
@@ -0,0 +1,22 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+var App = require('app');
+
+App.PigModalController = Ember.ObjectController.extend({ 
+});

http://git-wip-us.apache.org/repos/asf/ambari/blob/5eb22214/contrib/views/pig/src/main/resources/ui/pig-web/app/controllers/pig.js
----------------------------------------------------------------------
diff --git a/contrib/views/pig/src/main/resources/ui/pig-web/app/controllers/pig.js b/contrib/views/pig/src/main/resources/ui/pig-web/app/controllers/pig.js
new file mode 100644
index 0000000..ed04971
--- /dev/null
+++ b/contrib/views/pig/src/main/resources/ui/pig-web/app/controllers/pig.js
@@ -0,0 +1,26 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+var App = require('app');
+
+App.PigController = Em.ArrayController.extend({
+  category: 'scripts',
+  openScripts: function() {
+    return this.get('content').filterBy('opened',true);
+  }.property('content.@each.opened')
+});

http://git-wip-us.apache.org/repos/asf/ambari/blob/5eb22214/contrib/views/pig/src/main/resources/ui/pig-web/app/controllers/pigHistory.js
----------------------------------------------------------------------
diff --git a/contrib/views/pig/src/main/resources/ui/pig-web/app/controllers/pigHistory.js b/contrib/views/pig/src/main/resources/ui/pig-web/app/controllers/pigHistory.js
new file mode 100644
index 0000000..433733e
--- /dev/null
+++ b/contrib/views/pig/src/main/resources/ui/pig-web/app/controllers/pigHistory.js
@@ -0,0 +1,28 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+var App = require('app');
+
+App.PigHistoryController = Em.ArrayController.extend({
+  content: [],
+  jobs: function() {
+    return this.get('content').filter(function(job, index, enumerable){
+      return job.get('status') != 'SUBMIT_FAILED';
+    });
+  }.property('content.@each.status')
+});

http://git-wip-us.apache.org/repos/asf/ambari/blob/5eb22214/contrib/views/pig/src/main/resources/ui/pig-web/app/controllers/pigJob.js
----------------------------------------------------------------------
diff --git a/contrib/views/pig/src/main/resources/ui/pig-web/app/controllers/pigJob.js b/contrib/views/pig/src/main/resources/ui/pig-web/app/controllers/pigJob.js
new file mode 100644
index 0000000..1ae96f8
--- /dev/null
+++ b/contrib/views/pig/src/main/resources/ui/pig-web/app/controllers/pigJob.js
@@ -0,0 +1,31 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+var App = require('app');
+
+
+App.JobController = App.EditController.extend({
+  needs:['poll'],
+  isJob:true,
+  category:'edit',
+  actions:{
+    returnToOriginal: function (job) {
+      this.transitionToRoute('pig.scriptEdit', job.get('scriptId'));
+    },
+  }
+});

http://git-wip-us.apache.org/repos/asf/ambari/blob/5eb22214/contrib/views/pig/src/main/resources/ui/pig-web/app/controllers/pigScriptEdit.js
----------------------------------------------------------------------
diff --git a/contrib/views/pig/src/main/resources/ui/pig-web/app/controllers/pigScriptEdit.js b/contrib/views/pig/src/main/resources/ui/pig-web/app/controllers/pigScriptEdit.js
new file mode 100644
index 0000000..597898b
--- /dev/null
+++ b/contrib/views/pig/src/main/resources/ui/pig-web/app/controllers/pigScriptEdit.js
@@ -0,0 +1,61 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+var App = require('app');
+
+App.PigScriptEditController = App.EditController.extend({
+  needs:['pig'],
+  isScript:true,
+  pigParams:Em.A(),
+
+  /*
+    Updates nav title when renaming script.
+   */
+  updateNavTitle:function (controller) {
+    var pigC = controller.get('controllers.pig')
+    if (!($.inArray(pigC.get('category'),['udfs','scripts','history'])>=0)){
+      pigC.set('category',this.get('content.name'));
+    }
+  }.observes('content.name'),
+
+  /*
+    Observes params (%VAR%) in sript file 
+    and updates pigParams object as they changes. 
+   */
+  pigParamsMatch:function (controller) {
+    var editorContent = this.get('content.pigScript.fileContent');
+    if (editorContent) {
+      var match_var = editorContent.match(/\%\w+\%/g);
+      if (match_var) {
+        var oldParams = controller.pigParams;
+        controller.set('pigParams',[]);
+        match_var.forEach(function (param) {
+          var suchParams = controller.pigParams.filterProperty('param',param);
+          if (suchParams.length == 0){
+            var oldParam = oldParams.filterProperty('param',param);
+            var oldValue = oldParam.get('firstObject.value');
+            controller.pigParams.pushObject(Em.Object.create({param:param,value:oldValue,title:param.replace(/%/g,'')}));
+          }
+        });
+      } else {
+        controller.set('pigParams',[]);
+      }
+    };
+  }.observes('content.pigScript.fileContent'),
+
+});

http://git-wip-us.apache.org/repos/asf/ambari/blob/5eb22214/contrib/views/pig/src/main/resources/ui/pig-web/app/controllers/pigScriptEditResults.js
----------------------------------------------------------------------
diff --git a/contrib/views/pig/src/main/resources/ui/pig-web/app/controllers/pigScriptEditResults.js b/contrib/views/pig/src/main/resources/ui/pig-web/app/controllers/pigScriptEditResults.js
new file mode 100644
index 0000000..f02f9f7
--- /dev/null
+++ b/contrib/views/pig/src/main/resources/ui/pig-web/app/controllers/pigScriptEditResults.js
@@ -0,0 +1,22 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+var App = require('app');
+
+App.PigScriptEditResultsController = Em.ObjectController.extend({
+});

http://git-wip-us.apache.org/repos/asf/ambari/blob/5eb22214/contrib/views/pig/src/main/resources/ui/pig-web/app/controllers/pigScriptList.js
----------------------------------------------------------------------
diff --git a/contrib/views/pig/src/main/resources/ui/pig-web/app/controllers/pigScriptList.js b/contrib/views/pig/src/main/resources/ui/pig-web/app/controllers/pigScriptList.js
new file mode 100644
index 0000000..0422de2
--- /dev/null
+++ b/contrib/views/pig/src/main/resources/ui/pig-web/app/controllers/pigScriptList.js
@@ -0,0 +1,23 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+var App = require('app');
+
+App.PigScriptListController = Em.ArrayController.extend({
+
+});

http://git-wip-us.apache.org/repos/asf/ambari/blob/5eb22214/contrib/views/pig/src/main/resources/ui/pig-web/app/controllers/pigUdfs.js
----------------------------------------------------------------------
diff --git a/contrib/views/pig/src/main/resources/ui/pig-web/app/controllers/pigUdfs.js b/contrib/views/pig/src/main/resources/ui/pig-web/app/controllers/pigUdfs.js
new file mode 100644
index 0000000..e855e04
--- /dev/null
+++ b/contrib/views/pig/src/main/resources/ui/pig-web/app/controllers/pigUdfs.js
@@ -0,0 +1,23 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+var App = require('app');
+
+App.PigUdfsController = Em.ArrayController.extend({
+  
+});

http://git-wip-us.apache.org/repos/asf/ambari/blob/5eb22214/contrib/views/pig/src/main/resources/ui/pig-web/app/controllers/poll.js
----------------------------------------------------------------------
diff --git a/contrib/views/pig/src/main/resources/ui/pig-web/app/controllers/poll.js b/contrib/views/pig/src/main/resources/ui/pig-web/app/controllers/poll.js
new file mode 100644
index 0000000..2fd5661
--- /dev/null
+++ b/contrib/views/pig/src/main/resources/ui/pig-web/app/controllers/poll.js
@@ -0,0 +1,56 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+var App = require('app');
+
+App.PollController = Ember.ObjectController.extend({
+  actions:{
+    killjob:function (job) {
+      var self = this;
+      job.kill(function () {
+        job.reload();
+        self.send('showAlert', {'message': Em.I18n.t('job.alert.job_killed',{title:self.get('title')}), status:'info'});
+      },function () {
+        self.send('showAlert', {'message': Em.I18n.t('job.alert.job_kill_error'), status:'error'});
+      });
+    },
+  },
+  pollster:Em.Object.create({
+    job:null,
+    start: function(job){
+      this.stop();
+      this.set('job',job);
+      this.timer = setInterval(this.onPoll.bind(this), 5000);
+      console.log('START polling. Job: ',this.get('job.id'),'. Timer: ',this.timer)
+    },
+    stop: function(){
+      this.set('job',null);
+      clearInterval(this.timer);
+      console.log('STOP polling. Job: ',this.get('job.id'),'. Timer: ',this.timer)
+    },
+    onPoll: function() {
+      if (this.job.get('needsPing')) {
+        console.log('DO polling. Job: ',this.get('job.id'),'. Timer: ', this.timer)
+        this.job.reload();
+      } else {
+        console.log('END polling. Job: ',this.get('job.id'),'. Timer: ',this.timer)
+        this.stop();
+      };
+    }
+  })
+});